feat: rename project from Validatrix to Nimcheck across all files and add CI pipeline

Rename the entire project from "Validatrix" to "Nimcheck" in README.md, Makefile, LESSONS_LEARNED.md, and all source references; add initial Gitea CI workflow with lint, test, and build jobs for Nim 2.0.0; expand .gitignore with comprehensive patterns for Nim, Python, editor, environment, and temporary files; add CONTRIBUTING.md and LICENSE (MIT) files to establish project governance and licensing.
This commit is contained in:
retoor 2026-07-08 08:01:58 +00:00
parent 659ea7ebe0
commit 72a7b661db
53 changed files with 425 additions and 248 deletions

72
.gitea/workflows/ci.yml Normal file
View File

@ -0,0 +1,72 @@
# Nimcheck CI pipeline
# Runs lint, test, and build on push and pull request.
#
# Requires a Gitea act_runner with the "ubuntu-latest" label
# (default label on the official gitea/act_runner image).
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
env:
NIM_VERSION: "2.0.0"
jobs:
# ------------------------------------------------------------------
# Lint: compile with full hints and warnings enabled
# ------------------------------------------------------------------
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Nim
run: |
curl https://nim-lang.org/choosenim/init.sh -sSf | sh -s -- -y "stable"
echo "$HOME/.nimble/bin" >> "$GITHUB_PATH"
- name: Lint
run: make lint
# ------------------------------------------------------------------
# Test: compile and run the full test suite
# ------------------------------------------------------------------
test:
name: Test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Nim
run: |
curl https://nim-lang.org/choosenim/init.sh -sSf | sh -s -- -y "stable"
echo "$HOME/.nimble/bin" >> "$GITHUB_PATH"
- name: Run tests
run: make test
# ------------------------------------------------------------------
# Build: produce the release binary (runs only after lint + test)
# ------------------------------------------------------------------
build:
name: Build
needs: [lint, test]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Nim
run: |
curl https://nim-lang.org/choosenim/init.sh -sSf | sh -s -- -y "stable"
echo "$HOME/.nimble/bin" >> "$GITHUB_PATH"
- name: Build
run: make build

86
.gitignore vendored
View File

@ -1,31 +1,83 @@
# Compiled binaries
bin/
# ── Nim ──────────────────────────────────────────────────────────────────
nimcache/
nimblecache/
*.exe
*.out
# Logs
*.log
# Python cache
__pycache__/
*.pyc
# OS files
.DS_Store
Thumbs.db
# Build artifacts
*.o
*.obj
*.a
*.so
*.dylib
# Test compiled binaries (source is .nim, binaries have no extension)
# ── Binaries (compiled output) ───────────────────────────────────────────
bin/
# ── Test compiled binaries (source is .nim, binaries have no extension) ──
tests/test_all
tests/test_bash
tests/test_nim
tests/test_php
tests/test_python
tests/test_javascript
tests/test_js
tests/test_html
tests/test_jinja
tests/test_json
tests/test_yaml
tests/test_toml
tests/test_mixed
tests/test_config
tests/test_fuzz
# Editor files
# ── Logs ─────────────────────────────────────────────────────────────────
*.log
# ── Python cache ─────────────────────────────────────────────────────────
__pycache__/
*.pyc
*.pyo
*.pyd
# ── OS files ─────────────────────────────────────────────────────────────
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
desktop.ini
# ── Editor files ─────────────────────────────────────────────────────────
*.swp
*.swo
*~
*.bak
*.orig
.vscode/
.idea/
*.sublime-project
*.sublime-workspace
# ── Environment / secrets ────────────────────────────────────────────────
.env
.env.local
.env.*.local
*.env
!.env.example
# ── Temporary / backup files ─────────────────────────────────────────────
/tmp/
*.tmp
*.temp
*.pid
# ── dpc agent logs ───────────────────────────────────────────────────────
dpc.log
# ── Coverage reports ─────────────────────────────────────────────────────
*.gcda
*.gcno
*.gcov
lcov.info
coverage/

35
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,35 @@
# Contributing to Nimcheck
Thank you for considering contributing to Nimcheck.
## Getting Started
1. Ensure you have Nim >= 2.0.0 installed.
2. Fork and clone the repository.
3. Run the test suite to verify your environment:
```bash
make test
```
## Development Workflow
- Use `make lint` to check for warnings before submitting.
- Run `make test` to run the full test suite. All tests must pass.
- Follow the existing code style and conventions.
## Adding a New Language
See [LESSONS_LEARNED.md](LESSONS_LEARNED.md) Section 16 for a detailed checklist
covering tokenizer, validator, registration, tests, and documentation.
## Pull Requests
- Open an issue to discuss significant changes before investing time.
- Keep PRs focused on a single change.
- Ensure all tests pass and no warnings are introduced.
- Update documentation if the public API changes.
## Code of Conduct
Be respectful. Keep discussions constructive.

View File

@ -1,11 +1,11 @@
# Validatrix Postmortem: Lessons Learned
# Nimcheck Postmortem: Lessons Learned
A root-cause analysis of every bug, anti-pattern, and structural issue
encountered during the development of the Validatrix validation framework.
encountered during the development of the Nimcheck validation framework.
**Date:** 2026-07-08
**Author:** AI-assisted analysis
**Project:** Validatrix — multi-language source code validation in Nim
**Project:** Nimcheck — multi-language source code validation in Nim
---
@ -32,7 +32,7 @@ encountered during the development of the Validatrix validation framework.
## 1. Executive Summary
Validatrix was developed by generating 7 tokenizers, 7 validators, and 3 config
Nimcheck was developed by generating 7 tokenizers, 7 validators, and 3 config
validators from a common template. The template itself had bugs, and the copy-
paste propagation amplified every defect across every language. Additionally,
the codebase accumulated unused imports, shadowed variables, and dead code
@ -44,7 +44,7 @@ because no compilation step was run between successive generations.
| Class | Description | Files Affected | Root Cause |
|---|---|---|---|
| 1 | Missing `var foundClosing` declaration | 4 tokenizers | Buggy template |
| 2 | `result` shadowing | 1 (validatrix.nim) | Nim implicit `result` vs. local `result` collision |
| 2 | `result` shadowing | 1 (nimcheck.nim) | Nim implicit `result` vs. local `result` collision |
| 3 | Unused/duplicate imports | ~22 files | No cleanup, cargo-cult imports |
| 4 | Debug imports on non-debug files | 15+ files | Template included debug unconditionally |
| 5 | `discard` violations | 1 (html_tokenizer) | `advance()` returns char but was discarded |
@ -52,7 +52,7 @@ because no compilation step was run between successive generations.
| 7 | Underscore-prefix identifiers | 1 (config_validators) | Nim doesn't allow `_` prefix |
| 8 | Zero-content `init_validators.nim` | 1 | Dead code left from architecture refactor |
| 9 | Missing `.gitignore` | 0 (repo-wide) | No `.gitignore` at repo init; build artifacts would be tracked |
| 10 | Directory name vs. project name mismatch | 1 (repo root) | Project directory `nimcheck` never renamed after project was renamed to `validatrix` |
| 10 | Directory name vs. project name mismatch | 1 (repo root) | Project directory `nimcheck` never renamed after project was renamed to `nimcheck` |
**250+ tests pass. Zero compiler warnings.**
@ -69,11 +69,11 @@ Every bug class is ordered by how many files it infected (most widespread first)
### Severity: CRITICAL — would produce wrong compilation (undeclared identifier)
### Files Affected
- `src/validatrix/tokenizers/nim_tokenizer.nim` (3 separate string contexts)
- `src/validatrix/tokenizers/bash_tokenizer.nim` (double-quoted strings)
- `src/validatrix/tokenizers/javascript_tokenizer.nim` (template literals)
- `src/validatrix/tokenizers/python_tokenizer.nim` (triple-quoted, f-strings, regular strings)
- `src/validatrix/tokenizers/jinja_tokenizer.nim` (removed a standalone `foundClosing = true` that declared nothing)
- `src/nimcheck/tokenizers/nim_tokenizer.nim` (3 separate string contexts)
- `src/nimcheck/tokenizers/bash_tokenizer.nim` (double-quoted strings)
- `src/nimcheck/tokenizers/javascript_tokenizer.nim` (template literals)
- `src/nimcheck/tokenizers/python_tokenizer.nim` (triple-quoted, f-strings, regular strings)
- `src/nimcheck/tokenizers/jinja_tokenizer.nim` (removed a standalone `foundClosing = true` that declared nothing)
### The Pattern
Every string-parsing loop in every tokenizer follows the same pattern:
@ -136,7 +136,7 @@ to `else:` in some cases for cleaner control flow.
### Severity: CRITICAL — causes incorrect field access at runtime
### Files Affected
- `src/validatrix.nim` (6+ locations across 4 functions)
- `src/nimcheck.nim` (6+ locations across 4 functions)
### The Pattern
```nim
@ -251,7 +251,7 @@ Every module that might need debug logging included:
```nim
import ../core/types, ../core/tokenizerbase, ../core/debug
```
But `../core/debug` was only needed when `defined(validatrixDebug)` was true.
But `../core/debug` was only needed when `defined(nimcheckDebug)` was true.
The debug module provides `debugEnter`, `debugLeave`, `debugLog`, `debugError`,
and `debugToken` — none of which are used when debug mode is off.
@ -287,7 +287,7 @@ suppression pragmas with comments for files that conditionally use them.
### Severity: MEDIUM (would fail compilation on stricter settings)
### Files Affected
- `src/validatrix/tokenizers/html_tokenizer.nim` (line 87)
- `src/nimcheck/tokenizers/html_tokenizer.nim` (line 87)
### What Went Wrong
```nim
@ -318,7 +318,7 @@ Changed `self.advance()` to `discard self.advance()`.
### Severity: CRITICAL (compilation error)
### Files Affected
- `src/validatrix/languages/config_validators.nim` (lines 113, 191)
- `src/nimcheck/languages/config_validators.nim` (lines 113, 191)
### What Went Wrong
Nim uses two syntaxes for named arguments in procedure calls:
@ -357,7 +357,7 @@ Changed `hint:` to `hint =` in the two function call sites.
### Severity: CRITICAL (compilation error)
### Files Affected
- `src/validatrix/languages/config_validators.nim` (line 110)
- `src/nimcheck/languages/config_validators.nim` (line 110)
### What Went Wrong
```nim
@ -389,8 +389,8 @@ Renamed `_indentStack` to `indentStack`.
### Severity: MEDIUM (warnings only, but architectural concern)
### Files Affected
- `src/validatrix/core/init_validators.nim` (dead, zero content)
- `src/validatrix.nim` (imports 8 validator modules for their side effects)
- `src/nimcheck/core/init_validators.nim` (dead, zero content)
- `src/nimcheck.nim` (imports 8 validator modules for their side effects)
- Every validator module (calls `init()` at module scope)
### The Pattern
@ -402,10 +402,10 @@ proc init*() =
init() # side-effect at module load time
```
Then `validatrix.nim` imports all validators:
Then `nimcheck.nim` imports all validators:
```nim
import validatrix/languages/nim_validator
import validatrix/languages/bash_validator
import nimcheck/languages/nim_validator
import nimcheck/languages/bash_validator
# ... etc
```
@ -419,7 +419,7 @@ side effect matters.
which happens in import order. If two validators conflict, the second
silently overwrites the first.
2. **No dynamic discovery:** To add a new language, you must edit
`validatrix.nim` to import it.
`nimcheck.nim` to import it.
3. **Compiler warnings are unavoidable** without pragma suppression.
4. **The `init_validators.nim` file** was supposed to centralize this
but became a stub that does nothing — dead code.
@ -434,7 +434,7 @@ side effect matters.
### Mitigation Applied
Added `{.warning[UnusedImport]:off.}` pragma around the validator imports
in `validatrix.nim` to suppress the warnings, with a comment explaining the
in `nimcheck.nim` to suppress the warnings, with a comment explaining the
side-effect pattern.
---
@ -450,8 +450,8 @@ side-effect pattern.
The repository was initialised (`git init`) without a `.gitignore` file.
Build artifacts existed on disk:
```
bin/validatrix 1.2 MB compiled binary
src/validatrix.out 1.2 MB build output
bin/nimcheck 1.2 MB compiled binary
src/nimcheck.out 1.2 MB build output
tests/test_all 3.4 MB compiled test binary
tests/test_bash 1.2 MB compiled test binary
tests/test_nim 1.1 MB compiled test binary
@ -501,39 +501,29 @@ Verified with `git add --dry-run` that only source files would be staged.
### Severity: LOW (cosmetic, but causes confusion)
### Files Affected
- Repository root directory (`/home/retoor/projects/nimcheck/`)
- Repository root directory
### The Pattern
The project was originally named `nimcheck` (or similar), and the repository
directory was created with that name. During development the project was
renamed to **Validatrix** -- the `.nimble` file, all source code, the
README, and every reference uses "validatrix" -- but the directory itself
was never renamed.
This means:
- `cd` paths are `/home/retoor/projects/nimcheck/` but everything inside
says `validatrix`
- Git remote URLs (when added) would reference `nimcheck`
- New developers cloning the repo get `nimcheck/` as the checkout directory
The project was originally named **Validatrix** with a repository root directory
named `nimcheck`. All source code, the `.nimble` file, README, and every
reference used "validatrix" while the checkout directory was "nimcheck".
This mismatch between project name and directory name caused confusion.
### Root Cause
- Directory rename was simply forgotten after the project rename.
- No checklist item says "rename the root directory when you rename a
project."
- The `git init` happened in the old directory before the rename.
- The directory was created with one name and the project was renamed but
the directory rename was missed.
- No checklist item existed saying "rename the root directory when you rename
a project."
### Prevention
- **Add a project-bootstrap checklist** item: "Verify the project directory
name matches the project name."
- **When renaming a project**: rename the directory, update git remote,
update CI paths, update any scripts that reference the full path.
- **Use `git mv`** if the rename needs to preserve history (but an empty
dir rename is just `mv`).
### Fix Applied
Documented here. To fix directory name: `mv nimcheck validatrix` and update
any scripts referencing the old path. Not applied yet (requires
coordinating with other tools referencing the path).
The project was eventually renamed from Validatrix to Nimcheck everywhere —
source code, documentation, `.nimble` file, and directory name now all match.
---
@ -621,13 +611,13 @@ in some places, leading to inconsistent reporting.
1. **Compile immediately** after any edit:
```bash
nim c --verbosity:0 src/validatrix.nim
nim c --verbosity:0 src/nimcheck.nim
```
This catches: undeclared identifiers, type mismatches, invalid syntax.
2. **Check warnings explicitly:**
```bash
nim c --warning[UnusedImport]:on --warning[UnusedResult]:on src/validatrix.nim 2>&1 | grep -E "Warning:|Hint:" | grep -v "Conf\|Link\|mm:\|Success"
nim c --warning[UnusedImport]:on --warning[UnusedResult]:on src/nimcheck.nim 2>&1 | grep -E "Warning:|Hint:" | grep -v "Conf\|Link\|mm:\|Success"
```
3. **Run the full test suite:**
@ -646,7 +636,7 @@ in some places, leading to inconsistent reporting.
- Add `nim check` to CI (type-checks without generating code, faster):
```bash
nim check src/validatrix.nim
nim check src/nimcheck.nim
```
- Add `--warning[ResultShadowed]:on` to project config.
@ -672,7 +662,7 @@ When adding a new language:
- [ ] Are all `toJson()` conversions using `.mapIt()` on sequences?
### Registration
- [ ] Is the validator added to the import list in `validatrix.nim`?
- [ ] Is the validator added to the import list in `nimcheck.nim`?
- [ ] Are the imports wrapped with `{.warning[UnusedImport]:off.}`?
- [ ] Does `supportedFlavors()` include the new language?
@ -697,9 +687,9 @@ A chronological log of every error encountered:
| 6 | `invalid expression: hint:` | `config_validators.nim:113,191` | Changed `hint:` to `hint =` |
| 7 | `statement not allowed` / `invalid indentation` | `detector.nim:404` | Fixed indentation of `discard e` in except block |
| 8 | `type mismatch` (toHashSet) | `nim_tokenizer.nim:40` | Restored `sets` import |
| 9 | `undeclared field: 'valid' for type JsonNode` | `validatrix.nim:202` | Changed `result.valid` to `r.valid` |
| 9 | `undeclared field: 'valid' for type JsonNode` | `nimcheck.nim:202` | Changed `result.valid` to `r.valid` |
| 10 | `invalid indentation` | `detector.nim` | Re-fixed after multiple partial edits |
| 11 | `expression of type 'char' not used` | `html_tokenizer.nim:87` | Changed `self.advance()` to `discard self.advance()` |
| 12 | ~50 unused import warnings | All tokenizers, validators, core files | Stripped imports, added pragma suppressions |
| 13 | ~5 XDeclaredButNotUsed hints | `bash_validator.nim`, `config_validators.nim`, `validatrix.nim` | Added `{.used.}` pragma or removed variable |
| 14 | ~3 DuplicateModuleImport hints | `validatrix.nim`, 3 tokenizers | Deduplicated import lines |
| 13 | ~5 XDeclaredButNotUsed hints | `bash_validator.nim`, `config_validators.nim`, `nimcheck.nim` | Added `{.used.}` pragma or removed variable |
| 14 | ~3 DuplicateModuleImport hints | `nimcheck.nim`, 3 tokenizers | Deduplicated import lines |

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 molodetz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,4 +1,4 @@
# Validatrix - Universal Source Code Validation Framework
# Nimcheck - Universal Source Code Validation Framework
# Makefile
NIMC = nim c
@ -17,11 +17,11 @@ all: build
build:
@mkdir -p $(BIN_DIR)
$(NIMC) $(NIMC_MACROS) --outdir:$(BIN_DIR) $(SRC_DIR)/validatrix.nim
$(NIMC) $(NIMC_MACROS) --outdir:$(BIN_DIR) $(SRC_DIR)/nimcheck.nim
build-debug:
@mkdir -p $(BIN_DIR)
$(NIMC) -d:validatrixDebug --outdir:$(BIN_DIR) $(SRC_DIR)/validatrix.nim
$(NIMC) -d:nimcheckDebug --outdir:$(BIN_DIR) $(SRC_DIR)/nimcheck.nim
# --- Test targets ---
@ -66,12 +66,12 @@ test-mixed:
# --- Debug mode ---
debug: build-debug
$(NIMC) -d:validatrixDebug -r $(TEST_DIR)/test_all.nim
$(NIMC) -d:nimcheckDebug -r $(TEST_DIR)/test_all.nim
# --- Lint / static analysis ---
lint:
$(NIMC) --hints:on --warnings:on $(SRC_DIR)/validatrix.nim
$(NIMC) --hints:on --warnings:on $(SRC_DIR)/nimcheck.nim
# --- Cleanup ---
@ -89,22 +89,22 @@ rebuild: clean build
# --- Coverage (requires nim-coverage) ---
coverage:
$(NIMC) -d:validatrixCoverage -r $(TEST_DIR)/test_all.nim
$(NIMC) -d:nimcheckCoverage -r $(TEST_DIR)/test_all.nim
# --- Validation command-line tool ---
validate: build
@echo "Usage: echo '<source>' | $(BIN_DIR)/validatrix validate --flavor=<lang>"
@echo " $(BIN_DIR)/validatrix validate --file=<path> [--flavor=<lang>]"
@echo "Usage: echo '<source>' | $(BIN_DIR)/nimcheck validate --flavor=<lang>"
@echo " $(BIN_DIR)/nimcheck validate --file=<path> [--flavor=<lang>]"
inspect: build
@echo "Usage: $(BIN_DIR)/validatrix inspect --file=<path> [--flavor=<lang>]"
@echo " $(BIN_DIR)/validatrix inspect --source=<code> --flavor=<lang>"
@echo "Usage: $(BIN_DIR)/nimcheck inspect --file=<path> [--flavor=<lang>]"
@echo " $(BIN_DIR)/nimcheck inspect --source=<code> --flavor=<lang>"
# --- Help ---
help:
@echo "Validatrix - Universal Source Code Validation Framework"
@echo "Nimcheck - Universal Source Code Validation Framework"
@echo ""
@echo "Targets:"
@echo " build - Compile the library"

View File

@ -1,6 +1,6 @@
# Validatrix
# Nimcheck
A multi-language source code validation framework written in Nim. Validatrix uses tokenizer-based validation to check syntax correctness across 10 languages and config formats, with auto-detection, comprehensive diagnostics, and a never-crash guarantee.
A multi-language source code validation framework written in Nim. Nimcheck uses tokenizer-based validation to check syntax correctness across 10 languages and config formats, with auto-detection, comprehensive diagnostics, and a never-crash guarantee.
## Features
@ -11,13 +11,13 @@ A multi-language source code validation framework written in Nim. Validatrix use
- **Never-crash guarantee** -- every validation path is wrapped in try/except; invalid input returns errors gracefully, never panics
- **JSON output** -- machine-readable diagnostics via `toJson()` on any validation result
- **Inspection API** -- extract module structure (imports, definitions, functions/classes) as JSON
- **Debug mode** -- compile with `-d:validatrixDebug` for detailed tokenization logging
- **Debug mode** -- compile with `-d:nimcheckDebug` for detailed tokenization logging
- **No external dependencies** -- pure Nim standard library
## Quick Start
```nim
import validatrix
import nimcheck
# Validate source code from a string
let r = validateSource("proc hello() = echo 'hi'", lfNim)
@ -89,10 +89,10 @@ nimble build
```bash
# Build the library
nim c src/validatrix.nim
nim c src/nimcheck.nim
# Build with debug mode
nim c -d:validatrixDebug src/validatrix.nim
nim c -d:nimcheckDebug src/nimcheck.nim
# Run all tests
nim c -r tests/test_all.nim
@ -100,28 +100,28 @@ nim c -r tests/test_all.nim
## CLI Usage
When compiled as a standalone binary (`make build` produces `bin/validatrix`):
When compiled as a standalone binary (`make build` produces `bin/nimcheck`):
```bash
# Validate a file
bin/validatrix validate --file=source.nim
bin/nimcheck validate --file=source.nim
# Validate source code directly
bin/validatrix validate --source="print('hi')" --flavor=python
bin/nimcheck validate --source="print('hi')" --flavor=python
# Read from stdin
echo "var x = 1" | bin/validatrix validate
echo "var x = 1" | bin/nimcheck validate
# Inspect source structure (returns JSON)
bin/validatrix inspect --file=source.py
bin/nimcheck inspect --file=source.py
# Detect language
bin/validatrix detect --file=unknown.txt
bin/validatrix detect --source="#!/usr/bin/env bash"
bin/nimcheck detect --file=unknown.txt
bin/nimcheck detect --source="#!/usr/bin/env bash"
# Version and help
bin/validatrix version
bin/validatrix help
bin/nimcheck version
bin/nimcheck help
```
## API Reference
@ -140,7 +140,7 @@ bin/validatrix help
| `reportFile(filePath, flavor)` | Get a human-readable validation report for a file (string) |
| `detectFlavor(source, filePath)` | Auto-detect language flavor |
| `supportedFlavors()` | List all registered language flavors (returns `seq[string]`) |
| `version()` | Get the Validatrix version string |
| `version()` | Get the Nimcheck version string |
| `enableDebug()` / `disableDebug()` | Toggle debug mode globally |
### Types
@ -217,8 +217,8 @@ nim c -r tests/test_all.nim
```
src/
validatrix.nim Public API entry point and CLI (isMainModule)
validatrix/
nimcheck.nim Public API entry point and CLI (isMainModule)
nimcheck/
core/
types.nim Core types: ValidationResult, ValidationError, LanguageFlavor
tokenizerbase.nim Abstract tokenizer base class
@ -260,7 +260,7 @@ tests/
```bash
make lint
# or manually:
nim c --hints:on --warnings:on src/validatrix.nim
nim c --hints:on --warnings:on src/nimcheck.nim
```
### Adding a new language
@ -276,16 +276,23 @@ The framework uses a layered architecture:
3. **Detector** -- identifies language from file extension, shebang, or content heuristics
4. **Reporting** -- formats errors as human-readable strings or structured JSON
Validators register themselves at import time via a side-effect factory pattern. The public API (`validatrix.nim`) imports all validators and re-exports core types for consumer convenience.
Validators register themselves at import time via a side-effect factory pattern. The public API (`nimcheck.nim`) imports all validators and re-exports core types for consumer convenience.
## Versioning
Current version: **0.1.0**
## Contributing
Contributions are welcome. Please open an issue to discuss your idea before
submitting a pull request. For detailed instructions on adding support for a new
language, see [LESSONS_LEARNED.md](LESSONS_LEARNED.md) Section 16.
## License
MIT
This project is licensed under the MIT License -- see the [LICENSE](LICENSE) file
for details.
## Author
molodetz -- DevPlace Code
molodetz

View File

@ -47,9 +47,9 @@ task test_mixed, "Run mixed file tests":
exec "nim c -r tests/test_mixed.nim"
task debug, "Run tests in debug mode":
exec "nim c -d:validatrixDebug -r tests/test_all.nim"
exec "nim c -d:nimcheckDebug -r tests/test_all.nim"
task build, "Build the library":
exec "nim c --lib src/validatrix.nim"
exec "nim c --lib src/nimcheck.nim"
# End

View File

@ -1,4 +1,4 @@
## Validatrix - Universal Source Code Validation Framework
## Nimcheck - Universal Source Code Validation Framework
##
## A comprehensive, extensible validation framework for all common
## programming languages and file formats. Provides tokenizer-based
@ -6,7 +6,7 @@
## consistent error reporting.
##
## Usage:
## import validatrix
## import nimcheck
## let r = validateSource("print('hello')", flavor=lfPython)
## let jsonResult = result.toJson()
##
@ -18,12 +18,12 @@
import std/[json, strutils, os, strformat, sequtils, algorithm]
# Core types and base classes — imported and re-exported for public API consumers
import validatrix/core/types
import validatrix/core/tokenizerbase
import validatrix/core/validatorbase
import validatrix/core/detector
import validatrix/core/debug
import validatrix/reporting/errors
import nimcheck/core/types
import nimcheck/core/tokenizerbase
import nimcheck/core/validatorbase
import nimcheck/core/detector
import nimcheck/core/debug
import nimcheck/reporting/errors
export types
export tokenizerbase
export validatorbase
@ -31,14 +31,14 @@ export errors
# Import all language validators (they register themselves on import)
{.warning[UnusedImport]:off.}
import validatrix/languages/nim_validator
import validatrix/languages/bash_validator
import validatrix/languages/python_validator
import validatrix/languages/javascript_validator
import validatrix/languages/php_validator
import validatrix/languages/html_validator
import validatrix/languages/jinja_validator
import validatrix/languages/config_validators
import nimcheck/languages/nim_validator
import nimcheck/languages/bash_validator
import nimcheck/languages/python_validator
import nimcheck/languages/javascript_validator
import nimcheck/languages/php_validator
import nimcheck/languages/html_validator
import nimcheck/languages/jinja_validator
import nimcheck/languages/config_validators
{.warning[UnusedImport]:on.}
# ---------------------------------------------------------------------------
@ -60,10 +60,10 @@ proc validateSource*(
## let r = validateSource("proc hello() = echo 'hi'", flavor=lfNim)
## let r = validateSource("var x = 1", flavor=lfUnknown) # auto-detect
when defined(validatrixDebug):
when defined(nimcheckDebug):
if options.debugMode and not debugEnabled:
enableDebug()
debugEnter("VALIDATRIX", "validateSource called")
debugEnter("NIMCHECK", "validateSource called")
try:
var opts = options
@ -118,9 +118,9 @@ proc validateSource*(
newSourceRange(newSourcePosition(0, 0, 0), newSourcePosition(0, 0, 0))
))
when defined(validatrixDebug):
when defined(nimcheckDebug):
if options.debugMode:
debugLeave("VALIDATRIX", &"Validation complete: valid={result.valid}, errors={result.errors.len}")
debugLeave("NIMCHECK", &"Validation complete: valid={result.valid}, errors={result.errors.len}")
result.debugOutput = getDebugOutput()
# ---------------------------------------------------------------------------
@ -141,9 +141,9 @@ proc validateFile*(
## let r = validateFile("src/main.nim")
## let r = validateFile("template.html.jinja", flavor=lfJinja)
when defined(validatrixDebug):
when defined(nimcheckDebug):
if options.debugMode:
debugEnter("VALIDATRIX", &"validateFile: {filePath}")
debugEnter("NIMCHECK", &"validateFile: {filePath}")
try:
if not fileExists(filePath):
@ -169,9 +169,9 @@ proc validateFile*(
result = validateSource(source, detectedFlavor, options, filePath)
when defined(validatrixDebug):
when defined(nimcheckDebug):
if options.debugMode:
debugLeave("VALIDATRIX", &"File validation complete: {result.errors.len} errors")
debugLeave("NIMCHECK", &"File validation complete: {result.errors.len} errors")
except Exception as e:
result = newValidationResult()
@ -252,12 +252,12 @@ proc detectFlavor*(source: string, filePath: string = ""): LanguageFlavor =
# ---------------------------------------------------------------------------
const
validatrixVersion* = "0.1.0"
validatrixDescription* = "Universal Source Code Validation Framework"
nimcheckVersion* = "0.1.0"
nimcheckDescription* = "Universal Source Code Validation Framework"
proc version*(): string =
## Get the Validatrix version string.
validatrixVersion
## Get the Nimcheck version string.
nimcheckVersion
proc supportedFlavors*(): seq[string] =
## Get list of all supported language flavors.
@ -285,13 +285,13 @@ proc disableDebug*() =
when isMainModule:
proc printUsage() =
echo &"Validatrix v{validatrixVersion} - {validatrixDescription}"
echo &"Nimcheck v{nimcheckVersion} - {nimcheckDescription}"
echo ""
echo "Usage:"
echo " validatrix validate [--file=<path> | --source=<code>] [--flavor=<lang>]"
echo " validatrix inspect [--file=<path> | --source=<code>] [--flavor=<lang>]"
echo " validatrix detect [--file=<path> | --source=<code>]"
echo " validatrix help"
echo " nimcheck validate [--file=<path> | --source=<code>] [--flavor=<lang>]"
echo " nimcheck inspect [--file=<path> | --source=<code>] [--flavor=<lang>]"
echo " nimcheck detect [--file=<path> | --source=<code>]"
echo " nimcheck help"
echo ""
echo "Options:"
echo " --file=<path> Source file to process"
@ -394,7 +394,7 @@ when isMainModule:
echo &" Confidence: {dconfidence * 100:.2f}%"
of "version", "--version", "-v":
echo &"Validatrix v{validatrixVersion}"
echo &"Nimcheck v{nimcheckVersion}"
of "help", "--help", "-h":
printUsage()

View File

@ -1,6 +1,6 @@
## Debug mode support for Validatrix.
## Debug mode support for Nimcheck.
##
## When compiled with -d:validatrixDebug, all validators and tokenizers
## When compiled with -d:nimcheckDebug, all validators and tokenizers
## produce detailed debug output that helps an LLM or developer trace
## exactly what the validator is doing.
@ -27,7 +27,7 @@ var
proc enableDebug*() =
## Enable debug output collection.
when defined(validatrixDebug):
when defined(nimcheckDebug):
debugEnabled = true
debugBuffer = @[]
debugIndent = 0
@ -36,13 +36,13 @@ proc enableDebug*() =
proc disableDebug*() =
## Disable debug output collection.
when defined(validatrixDebug):
when defined(nimcheckDebug):
debugLog("DEBUG", "Debug mode disabled")
debugEnabled = false
proc isDebugEnabled*(): bool =
## Check if debug mode is active.
when defined(validatrixDebug):
when defined(nimcheckDebug):
result = debugEnabled
else:
result = false
@ -58,7 +58,7 @@ proc clearDebug*() =
proc debugLog*(category: string, message: string) =
## Log a debug message with category.
when defined(validatrixDebug):
when defined(nimcheckDebug):
if debugEnabled:
let indent = repeat(" "Indent)
let timestamp = now().format("HH:mm:ss.fff")
@ -66,13 +66,13 @@ proc debugLog*(category: string, message: string) =
proc debugEnter*(category: string, message: string) =
## Log entry into a scope and increase indent.
when defined(validatrixDebug):
when defined(nimcheckDebug):
debugLog(category, "--> " & message)
debugIndent += 1
proc debugLeave*(category: string, message: string = "") =
## Decrease indent and log exit from a scope.
when defined(validatrixDebug):
when defined(nimcheckDebug):
if debugIndent > 0:
debugIndent -= 1
let indentMsg = if message.len > 0: "<-- " & message else: "<--"
@ -84,12 +84,12 @@ proc debugLeave*(category: string, message: string = "") =
proc debugTimerStart*(name: string) =
## Start a named timer.
when defined(validatrixDebug):
when defined(nimcheckDebug):
debugTimers[name] = epochTime()
proc debugTimerStop*(name: string): float =
## Stop a named timer and return elapsed ms.
when defined(validatrixDebug):
when defined(nimcheckDebug):
let start = debugTimers.getOrDefault(name, 0.0)
if start > 0.0:
result = (epochTime() - start) * 1000.0
@ -108,19 +108,19 @@ proc debugTimerStopAndLog*(name: string) =
proc getDebugOutput*(): string =
## Get the complete debug output as a string.
when defined(validatrixDebug):
when defined(nimcheckDebug):
result = debugBuffer.join("\n")
else:
result = ""
proc debugToken*(token: Token) =
## Log a token.
when defined(validatrixDebug):
when defined(nimcheckDebug):
debugLog("TOKEN", &"[{token.kind}] '{token.value}' @ L{token.position.line}:{token.position.column}")
proc debugError*(err: ValidationError) =
## Log a validation error.
when defined(validatrixDebug):
when defined(nimcheckDebug):
debugLog("ERROR", &"[{err.code}] {err.severity}: {err.message} @ L{err.position.line}:{err.position.column}")
if err.hint.len > 0:
debugLog("HINT", err.hint)

View File

@ -1,4 +1,4 @@
## Language (flavor) auto-detection for Validatrix.
## Language (flavor) auto-detection for Nimcheck.
##
## Accurately detects programming language from:
## 1. File extension
@ -360,14 +360,14 @@ proc detectFlavor*(
## When explicitFlavor is provided and not lfUnknown, returns that.
## Otherwise, uses the best available detection method.
when defined(validatrixDebug):
when defined(nimcheckDebug):
if isDebugEnabled():
debugEnter("DETECTOR", "Detecting language flavor")
try:
# 1. Explicit flavor
if explicitFlavor != lfUnknown:
when defined(validatrixDebug):
when defined(nimcheckDebug):
if isDebugEnabled():
debugLog("DETECTOR", &"Using explicit flavor: {explicitFlavor}")
return (explicitFlavor, fdmExplicit, 1.0)
@ -377,7 +377,7 @@ proc detectFlavor*(
let ext = filePath.toLowerAscii()
for extension, flavor in extensionMap.pairs():
if ext.endsWith(extension) or ext == extension:
when defined(validatrixDebug):
when defined(nimcheckDebug):
if isDebugEnabled():
debugLog("DETECTOR", &"Detected by extension '{extension}': {flavor}")
return (flavor, fdmExtension, 0.9)
@ -385,7 +385,7 @@ proc detectFlavor*(
# 3. Shebang detection
let (shebangFlavor, shebangMethod) = detectByShebang(source)
if shebangFlavor != lfUnknown:
when defined(validatrixDebug):
when defined(nimcheckDebug):
if isDebugEnabled():
debugLog("DETECTOR", &"Detected by shebang: {shebangFlavor}")
return (shebangFlavor, shebangMethod, 0.95)
@ -394,18 +394,18 @@ proc detectFlavor*(
if source.len > 0:
let (contentFlavor, contentMethod, confidence) = detectByContent(source, filePath)
if contentFlavor != lfUnknown:
when defined(validatrixDebug):
when defined(nimcheckDebug):
if isDebugEnabled():
debugLog("DETECTOR", &"Detected by content: {contentFlavor} (confidence: {confidence})")
return (contentFlavor, contentMethod, confidence)
except Exception as e:
discard e
when defined(validatrixDebug):
when defined(nimcheckDebug):
if isDebugEnabled():
debugLog("DETECTOR", &"Detection error: {e.msg}")
when defined(validatrixDebug):
when defined(nimcheckDebug):
if isDebugEnabled():
debugLog("DETECTOR", "Could not determine flavor")
debugLeave("DETECTOR")

View File

@ -1,7 +1,7 @@
## Validator registration — called at module load time.
##
## Each language validator registers itself here.
## This file is imported by the main validatrix.nim module.
## This file is imported by the main nimcheck.nim module.
import ./types, ./validatorbase

View File

@ -1,4 +1,4 @@
## Abstract base tokenizer for Validatrix.
## Abstract base tokenizer for Nimcheck.
##
## All language-specific tokenizers inherit from this base class.
## Provides position tracking, error recording, and common tokenization helpers.
@ -144,7 +144,7 @@ proc emitToken*(self: TokenizerBase, kind: TokenKind, value: string, startPos: S
range: range
)
self.tokens.add(token)
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugToken(token)
@ -171,7 +171,7 @@ proc recordError*(
let hintVal = hint
let err = newValidationError(severity, message, code, position, range, hint = hintVal)
self.errors.add(err)
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugError(err)
@ -209,7 +209,7 @@ proc validateBrackets*(self: TokenizerBase): seq[ValidationError] =
hint = hintStr
)
result.add(err)
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugError(err)
self.errors.add(result)

View File

@ -1,4 +1,4 @@
## Validatrix Core Types
## Nimcheck Core Types
##
## Defines all foundational types used throughout the validation framework.
## Every validator, tokenizer, and reporter shares these types for consistency.

View File

@ -1,4 +1,4 @@
## Abstract base validator for Validatrix.
## Abstract base validator for Nimcheck.
##
## All language-specific validators inherit from this base class.
## Provides the common validation pipeline: tokenize -> analyze -> report.
@ -61,7 +61,7 @@ method buildModuleInfo*(self: ValidatorBase) {.base, gcsafe.} =
method validate*(self: ValidatorBase): ValidationResult {.base, gcsafe.} =
## Run the full validation pipeline.
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
if not debugEnabled:
enableDebug()
@ -81,11 +81,11 @@ method validate*(self: ValidatorBase): ValidationResult {.base, gcsafe.} =
# 2. Create and run tokenizer
self.tokenizer = self.createTokenizer()
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugTimerStart("tokenize")
self.tokenizer.tokenize()
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
discard debugTimerStop("tokenize")
debugLog("VALIDATE", &"Tokenized: {self.tokenizer.tokens.len} tokens, {self.tokenizer.errors.len} errors")
@ -94,14 +94,14 @@ method validate*(self: ValidatorBase): ValidationResult {.base, gcsafe.} =
self.result.errors.add(self.tokenizer.getErrors())
# 4. Structural analysis
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugEnter("ANALYZE", "Running structural analysis")
self.analyzeTokens()
self.buildModuleInfo()
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugLeave("ANALYZE")
@ -131,14 +131,14 @@ method validate*(self: ValidatorBase): ValidationResult {.base, gcsafe.} =
newSourceRange(newSourcePosition(0, 0, 0), newSourcePosition(0, 0, 0)),
hint = "This is a bug in the validator — please report it"
))
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugLog("EXCEPTION", &"Unhandled exception: {e.msg}")
# 7. Duration
self.result.durationMs = (epochTime() - self.startTime) * 1000.0
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugTimerStopAndLog("total")
self.result.debugOutput = getDebugOutput()

View File

@ -1,4 +1,4 @@
## Bash/Shell validator for Validatrix.
## Bash/Shell validator for Nimcheck.
##
## Validates Bash/shell scripts, checking structural balance and common issues.
@ -40,7 +40,7 @@ method createTokenizer*(self: BashValidator): TokenizerBase =
method analyzeTokens*(self: BashValidator) =
## Analyze Bash-specific patterns.
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugEnter("BASH_ANALYZE", "Analyzing Bash structure")
@ -105,7 +105,7 @@ method analyzeTokens*(self: BashValidator) =
hint = "Add missing 'esac' to close the case block"
))
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugLog("BASH_ANALYZE", &"if/fi: {ifCount}/{fiCount}, for/done: {forCount}/{doneCount}, case/esac: {caseCount}/{esacCount}")
debugLeave("BASH_ANALYZE")

View File

@ -1,4 +1,4 @@
## JSON, YAML, and TOML config validators for Validatrix.
## JSON, YAML, and TOML config validators for Nimcheck.
##
## These use built-in parsers where possible for accuracy.
@ -29,7 +29,7 @@ method createTokenizer*(self: JSONValidator): TokenizerBase =
method validate*(self: JSONValidator): ValidationResult =
## Override validate to use native JSON parser.
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugEnter("JSON_VALIDATE", "Validating JSON")
@ -69,7 +69,7 @@ method validate*(self: JSONValidator): ValidationResult =
newSourcePosition(1, 1, 0), newSourceRange(newSourcePosition(1, 1, 0), newSourcePosition(1, 1, 0))))
self.result.durationMs = (epochTime() - self.startTime) * 1000.0
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode: debugLeave("JSON_VALIDATE")
return self.result
@ -95,7 +95,7 @@ method createTokenizer*(self: YAMLValidator): TokenizerBase =
result = newTokenizerBase(self.source, self.options)
method validate*(self: YAMLValidator): ValidationResult =
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugEnter("YAML_VALIDATE", "Validating YAML")
@ -153,7 +153,7 @@ method validate*(self: YAMLValidator): ValidationResult =
newSourcePosition(1,1,0), newSourceRange(newSourcePosition(1,1,0), newSourcePosition(1,1,0))))
self.result.durationMs = (epochTime() - self.startTime) * 1000.0
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode: debugLeave("YAML_VALIDATE")
return self.result
@ -178,7 +178,7 @@ method createTokenizer*(self: TOMLValidator): TokenizerBase =
result = newTokenizerBase(self.source, self.options)
method validate*(self: TOMLValidator): ValidationResult =
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugEnter("TOML_VALIDATE", "Validating TOML")
@ -235,7 +235,7 @@ method validate*(self: TOMLValidator): ValidationResult =
newSourcePosition(1,1,0), newSourceRange(newSourcePosition(1,1,0), newSourcePosition(1,1,0))))
self.result.durationMs = (epochTime() - self.startTime) * 1000.0
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode: debugLeave("TOML_VALIDATE")
return self.result

View File

@ -1,4 +1,4 @@
## HTML/XML validator for Validatrix.
## HTML/XML validator for Nimcheck.
import std/[json, tables]
{.warning[UnusedImport]:off.}
@ -22,12 +22,12 @@ method createTokenizer*(self: HTMLValidator): TokenizerBase =
result = newHTMLTokenizer(self.source, self.options)
method analyzeTokens*(self: HTMLValidator) =
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode: debugEnter("HTML_ANALYZE", "Analyzing HTML")
procCall ValidatorBase(self).analyzeTokens()
for tok in self.tokenizer.tokens:
if tok.kind == tkComment: self.result.moduleInfo.comments += 1
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode: debugLeave("HTML_ANALYZE")
proc init*() =

View File

@ -1,4 +1,4 @@
## JavaScript/TypeScript validator for Validatrix.
## JavaScript/TypeScript validator for Nimcheck.
import std/[json, tables]
{.warning[UnusedImport]:off.}
@ -22,7 +22,7 @@ method createTokenizer*(self: JavaScriptValidator): TokenizerBase =
result = newJavaScriptTokenizer(self.source, self.options)
method analyzeTokens*(self: JavaScriptValidator) =
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugEnter("JS_ANALYZE", "Analyzing JS structure")
@ -65,7 +65,7 @@ method analyzeTokens*(self: JavaScriptValidator) =
discard
i += 1
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugLeave("JS_ANALYZE")

View File

@ -1,4 +1,4 @@
## Jinja2 template validator for Validatrix.
## Jinja2 template validator for Nimcheck.
import std/[json, strformat, tables]
{.warning[UnusedImport]:off.}
@ -22,7 +22,7 @@ method createTokenizer*(self: JinjaValidator): TokenizerBase =
result = newJinjaTokenizer(self.source, self.options)
method analyzeTokens*(self: JinjaValidator) =
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode: debugEnter("JINJA_ANALYZE", "Analyzing Jinja structure")
procCall ValidatorBase(self).analyzeTokens()
@ -90,7 +90,7 @@ method analyzeTokens*(self: JinjaValidator) =
newSourceRange(newSourcePosition(1, 1, 0), newSourcePosition(1, 1, 0)),
hint = &"Add a matching 'end{b}' tag"))
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode: debugLeave("JINJA_ANALYZE")
proc init*() =

View File

@ -1,4 +1,4 @@
## Nim language validator for Validatrix.
## Nim language validator for Nimcheck.
##
## Validates Nim source code using the Nim tokenizer.
## Handles common structural patterns and reports errors consistently.
@ -41,7 +41,7 @@ method createTokenizer*(self: NimValidator): TokenizerBase =
method analyzeTokens*(self: NimValidator) =
## Analyze Nim-specific structural patterns.
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugEnter("NIM_ANALYZE", "Analyzing Nim structure")
@ -105,7 +105,7 @@ method analyzeTokens*(self: NimValidator) =
discard
i += 1
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugLeave("NIM_ANALYZE", &"Found {self.result.moduleInfo.functions.len} functions, {self.result.moduleInfo.classes.len} types")
@ -120,7 +120,7 @@ method buildModuleInfo*(self: NimValidator) =
self.result.moduleInfo.totalTokens = self.tokenizer.tokens.len
# Debug info
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
self.result.moduleInfo.debugInfo = %*{
"language": "Nim",

View File

@ -1,4 +1,4 @@
## PHP validator for Validatrix.
## PHP validator for Nimcheck.
import std/[json, tables]
{.warning[UnusedImport]:off.}
@ -22,7 +22,7 @@ method createTokenizer*(self: PHPValidator): TokenizerBase =
result = newPHPTokenizer(self.source, self.options)
method analyzeTokens*(self: PHPValidator) =
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugEnter("PHP_ANALYZE", "Analyzing PHP structure")
@ -61,7 +61,7 @@ method analyzeTokens*(self: PHPValidator) =
else: discard
i += 1
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugLeave("PHP_ANALYZE")

View File

@ -1,4 +1,4 @@
## Python language validator for Validatrix.
## Python language validator for Nimcheck.
import std/[json, tables]
{.warning[UnusedImport]:off.}
@ -22,7 +22,7 @@ method createTokenizer*(self: PythonValidator): TokenizerBase =
result = newPythonTokenizer(self.source, self.options)
method analyzeTokens*(self: PythonValidator) =
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugEnter("PYTHON_ANALYZE", "Analyzing Python structure")
@ -77,7 +77,7 @@ method analyzeTokens*(self: PythonValidator) =
discard
i += 1
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugLeave("PYTHON_ANALYZE")

View File

@ -1,4 +1,4 @@
## Error reporting and formatting for Validatrix.
## Error reporting and formatting for Nimcheck.
##
## Provides consistent error formatting across all language validators,
## including human-readable and machine-readable (JSON) output.

View File

@ -1,4 +1,4 @@
## Bash/Shell tokenizer for Validatrix.
## Bash/Shell tokenizer for Nimcheck.
##
## Tokenizes Bash/Sh/Zsh source code including:
## - Here-documents (<<EOF)
@ -61,7 +61,7 @@ proc newBashTokenizer*(source: string, options: ValidationOptions = newValidatio
method tokenize*(self: BashTokenizer) =
## Tokenize Bash source code.
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugEnter("BASH_TOKENIZER", "Starting Bash tokenization")
@ -312,6 +312,6 @@ method tokenize*(self: BashTokenizer) =
# End of file
self.emitToken(tkEndOfFile, "", self.currentPos())
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugLeave("BASH_TOKENIZER", &"Tokenization complete: {self.tokens.len} tokens")

View File

@ -1,4 +1,4 @@
## HTML/XML tokenizer for Validatrix.
## HTML/XML tokenizer for Nimcheck.
import std/[strformat, sets, json, sequtils, unicode]
{.warning[UnusedImport]:off.}
@ -31,7 +31,7 @@ proc newHTMLTokenizer*(source: string, options: ValidationOptions = newValidatio
result.isXml = isXml
method tokenize*(self: HTMLTokenizer) =
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugEnter("HTML_TOKENIZER", "Starting HTML tokenization")
@ -157,6 +157,6 @@ method tokenize*(self: HTMLTokenizer) =
)
self.emitToken(tkEndOfFile, "", self.currentPos())
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugLeave("HTML_TOKENIZER", &"Complete: {self.tokens.len} tokens")

View File

@ -1,4 +1,4 @@
## JavaScript/TypeScript tokenizer for Validatrix.
## JavaScript/TypeScript tokenizer for Nimcheck.
import std/[strformat, sets, json, sequtils, unicode]
{.warning[UnusedImport]:off.}
@ -36,7 +36,7 @@ proc newJavaScriptTokenizer*(source: string, options: ValidationOptions = newVal
)
method tokenize*(self: JavaScriptTokenizer) =
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugEnter("JS_TOKENIZER", "Starting JS/TS tokenization")
@ -223,6 +223,6 @@ method tokenize*(self: JavaScriptTokenizer) =
self.emitToken(tkError, $self.advance(), startPos)
self.emitToken(tkEndOfFile, "", self.currentPos())
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugLeave("JS_TOKENIZER", &"Complete: {self.tokens.len} tokens")

View File

@ -1,4 +1,4 @@
## Jinja2 template tokenizer for Validatrix.
## Jinja2 template tokenizer for Nimcheck.
##
## Handles mixed Jinja2 template syntax ({{ }}, {% %}, {# #})
## embedded inside HTML/text content.
@ -37,7 +37,7 @@ proc newJinjaTokenizer*(source: string, options: ValidationOptions = newValidati
result.inBlockTag = false
method tokenize*(self: JinjaTokenizer) =
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugEnter("JINJA_TOKENIZER", "Starting Jinja tokenization")
@ -118,6 +118,6 @@ method tokenize*(self: JinjaTokenizer) =
self.emitToken(tkTemplateTag, text, startPos)
self.emitToken(tkEndOfFile, "", self.currentPos())
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugLeave("JINJA_TOKENIZER", &"Complete: {self.tokens.len} tokens")

View File

@ -1,4 +1,4 @@
## Nim language tokenizer for Validatrix.
## Nim language tokenizer for Nimcheck.
##
## Tokenizes Nim source code following Nim's lexical rules including:
## - Multi-line strings (""")
@ -65,7 +65,7 @@ proc newNimTokenizer*(source: string, options: ValidationOptions = newValidation
method tokenize*(self: NimTokenizer) =
## Tokenize Nim source code.
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugEnter("NIM_TOKENIZER", "Starting Nim tokenization")
@ -341,6 +341,6 @@ method tokenize*(self: NimTokenizer) =
# End of file
self.emitToken(tkEndOfFile, "", self.currentPos())
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugLeave("NIM_TOKENIZER", &"Tokenization complete: {self.tokens.len} tokens")

View File

@ -1,4 +1,4 @@
## PHP tokenizer for Validatrix.
## PHP tokenizer for Nimcheck.
##
## Handles mixed PHP/HTML content (template mode).
@ -43,7 +43,7 @@ proc newPHPTokenizer*(source: string, options: ValidationOptions = newValidation
result.inPhpMode = false
method tokenize*(self: PHPTokenizer) =
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugEnter("PHP_TOKENIZER", "Starting PHP tokenization")
@ -221,6 +221,6 @@ method tokenize*(self: PHPTokenizer) =
self.emitToken(tkError, $self.advance(), startPos)
self.emitToken(tkEndOfFile, "", self.currentPos())
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugLeave("PHP_TOKENIZER", &"Complete: {self.tokens.len} tokens (PHP mode: {self.inPhpMode})")

View File

@ -1,4 +1,4 @@
## Python tokenizer for Validatrix.
## Python tokenizer for Nimcheck.
##
## Tokenizes Python source code including:
## - Single/double quoted strings
@ -70,7 +70,7 @@ proc getIndentLevel*(line: string): int =
method tokenize*(self: PythonTokenizer) =
## Tokenize Python source code.
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugEnter("PYTHON_TOKENIZER", "Starting Python tokenization")
@ -349,6 +349,6 @@ method tokenize*(self: PythonTokenizer) =
# End of file
self.emitToken(tkEndOfFile, "", self.currentPos())
when defined(validatrixDebug):
when defined(nimcheckDebug):
if self.options.debugMode:
debugLeave("PYTHON_TOKENIZER", &"Tokenization complete: {self.tokens.len} tokens")

View File

@ -1,4 +1,4 @@
## Validatrix master test runner.
## Nimcheck master test runner.
## Compile: nim c -r tests/test_all.nim
import ./test_nim

View File

@ -1,7 +1,7 @@
## Bash language validator tests.
import std/[unittest, strutils, strformat]
import ../src/validatrix
import ../src/nimcheck
import test_common
proc checkValid(result: ValidationResult, context: string = "") =

View File

@ -3,7 +3,7 @@
## nesting extremes, unicode bombs, binary injection, and more.
import std/[unittest, strutils, strformat, json]
import ../src/validatrix
import ../src/nimcheck
proc checkValid(result: ValidationResult, context: string = "") =
if result.errors.len > 0:

View File

@ -1,4 +1,4 @@
## Common test patterns for Validatrix tests.
## Common test patterns for Nimcheck tests.
## This module provides code snippets used across test suites.
## Import it, then reference the const values directly.

View File

@ -1,7 +1,7 @@
## Config file (JSON, YAML, TOML) validator tests.
import std/[unittest, strutils, strformat]
import ../src/validatrix
import ../src/nimcheck
import test_common
proc checkValid(result: ValidationResult, context: string = "") =

View File

@ -1,8 +1,8 @@
## Fuzz testing module -- Validatrix against random, binary, and malicious inputs.
## Fuzz testing module -- Nimcheck against random, binary, and malicious inputs.
## Auto-generated. Tests framework robustness, never-crash guarantee.
import std/[unittest, strutils, strformat, math, sequtils]
import ../src/validatrix
import ../src/nimcheck
const allLangs* = [lfNim, lfBash, lfPython, lfJavaScript, lfPHP, lfHTML, lfJinja, lfJSON, lfYAML, lfTOML]
const threeLangs* = [lfNim, lfPython, lfJSON]

View File

@ -1,7 +1,7 @@
## HTML language validator tests.
import std/[unittest, strutils, strformat]
import ../src/validatrix
import ../src/nimcheck
import test_common
proc checkValid(result: ValidationResult, context: string = "") =

View File

@ -3,7 +3,7 @@
## nesting extremes, unicode bombs, binary injection, and more.
import std/[unittest, strutils, strformat, json]
import ../src/validatrix
import ../src/nimcheck
proc checkValid(result: ValidationResult, context: string = "") =
if result.errors.len > 0:

View File

@ -1,7 +1,7 @@
## JavaScript language validator tests.
import std/[unittest, strutils, strformat]
import ../src/validatrix
import ../src/nimcheck
import test_common
proc checkValid(result: ValidationResult, context: string = "") =

View File

@ -3,7 +3,7 @@
## nesting extremes, unicode bombs, binary injection, and more.
import std/[unittest, strutils, strformat, json]
import ../src/validatrix
import ../src/nimcheck
proc checkValid(result: ValidationResult, context: string = "") =
if result.errors.len > 0:

View File

@ -1,7 +1,7 @@
## Jinja template validator tests.
import std/[unittest, strutils, strformat]
import ../src/validatrix
import ../src/nimcheck
import test_common
proc checkValid(result: ValidationResult, context: string = "") =

View File

@ -3,7 +3,7 @@
## nesting extremes, unicode bombs, binary injection, and more.
import std/[unittest, strutils, strformat, json]
import ../src/validatrix
import ../src/nimcheck
proc checkValid(result: ValidationResult, context: string = "") =
if result.errors.len > 0:

View File

@ -3,7 +3,7 @@
## nesting extremes, unicode bombs, binary injection, and more.
import std/[unittest, strutils, strformat, json]
import ../src/validatrix
import ../src/nimcheck
proc checkValid(result: ValidationResult, context: string = "") =
if result.errors.len > 0:

View File

@ -1,7 +1,7 @@
## Mixed template file (Jinja + HTML) validator tests.
import std/[unittest, strutils]
import ../src/validatrix
import ../src/nimcheck
suite "Mixed File Validator":
test "validateFile on .html.j2 mixed file":

View File

@ -1,7 +1,7 @@
## Nim language validator tests.
import std/[unittest, strutils, strformat]
import ../src/validatrix
import ../src/nimcheck
import test_common
proc checkValid(result: ValidationResult, context: string = "") =

View File

@ -3,7 +3,7 @@
## nesting extremes, unicode bombs, binary injection, and more.
import std/[unittest, strutils, strformat, json]
import ../src/validatrix
import ../src/nimcheck
proc checkValid(result: ValidationResult, context: string = "") =
if result.errors.len > 0:

View File

@ -1,7 +1,7 @@
## PHP language validator tests.
import std/[unittest, strutils, strformat]
import ../src/validatrix
import ../src/nimcheck
import test_common
proc checkValid(result: ValidationResult, context: string = "") =

View File

@ -3,7 +3,7 @@
## nesting extremes, unicode bombs, binary injection, and more.
import std/[unittest, strutils, strformat, json]
import ../src/validatrix
import ../src/nimcheck
proc checkValid(result: ValidationResult, context: string = "") =
if result.errors.len > 0:

View File

@ -1,7 +1,7 @@
## Python language validator tests.
import std/[unittest, strutils, strformat]
import ../src/validatrix
import ../src/nimcheck
import test_common
proc checkValid(result: ValidationResult, context: string = "") =

View File

@ -3,7 +3,7 @@
## nesting extremes, unicode bombs, binary injection, and more.
import std/[unittest, strutils, strformat, json]
import ../src/validatrix
import ../src/nimcheck
proc checkValid(result: ValidationResult, context: string = "") =
if result.errors.len > 0:

View File

@ -3,7 +3,7 @@
## nesting extremes, unicode bombs, binary injection, and more.
import std/[unittest, strutils, strformat, json]
import ../src/validatrix
import ../src/nimcheck
proc checkValid(result: ValidationResult, context: string = "") =
if result.errors.len > 0:

View File

@ -3,7 +3,7 @@
## nesting extremes, unicode bombs, binary injection, and more.
import std/[unittest, strutils, strformat, json]
import ../src/validatrix
import ../src/nimcheck
proc checkValid(result: ValidationResult, context: string = "") =
if result.errors.len > 0: