sloc-web 1.2.1

Source line analysis tool with CLI, web UI, HTML/PDF reports, and CI/CD integration
Documentation

oxide-sloc

CI Release Docker Latest Release crates.io License: AGPL-3.0-or-later

oxide-sloc is a Rust-based source line analysis tool — IEEE 1045-1992 compliant, more than a line counter.

Quick Start

Install via Cargo (requires Rust):

cargo install oxide-sloc
oxide-sloc serve          # web UI at http://127.0.0.1:4317
oxide-sloc analyze ./my-repo --plain

Or use a pre-built binary:

Platform Install Launch
Windows 10/11 bash install.sh (Git Bash) bash run.sh (Git Bash)
Linux — RHEL 8/9, Ubuntu, Debian bash install.sh bash run.sh

The install script uses a pre-built binary from dist/ if present, or builds from vendored sources when Rust is available. On success, the web UI opens at http://127.0.0.1:4317.

For air-gapped setup, CI, and Docker, see docs/airgap.md.


Features

  • CLIanalyze / report / diff / serve / send / init with a full flag set
  • Localhost web UI — guided 4-step flow with light/dark theme, auto browser-open
  • Quick Scan — one-click scan from step 1 using all defaults
  • Server mode--server binds to 0.0.0.0, suppresses browser auto-open
  • IEEE 1045-1992 physical SLOC — configurable counting parameters: mixed-line policy, continuation lines, compiler directives, blank-in-comment classification
  • Symbol counting — lexical detection of functions, classes, variables, and imports per file
  • Rich HTML reports — per-file breakdown, language charts, warning analysis
  • PDF export — background generation via locally installed Chromium
  • CSV / Excel export — from CLI flags or the report nav bar (4-sheet workbook)
  • Scan history & delta tracking — every run is saved; re-scan to see lines added/removed
  • Side-by-side diff view — compare any two scans with 4 chart types at /compare
  • Git submodule support — per-submodule HTML sub-reports
  • Metrics API — JSON endpoints for CI/CD dashboards
  • SVG badge endpoint — embed live code-line counts in READMEs or Confluence
  • Embeddable summary widget<iframe> drop-in for internal wikis
  • Report deliverysend command: SMTP email or JSON webhook POST
  • CI/CD ready — Jenkinsfile, GitHub Actions, GitLab CI included
  • Docker image — auto-published to GHCR on main and release tags
  • Air-gap / offline — all crate dependencies vendored; Chart.js compiled in; no CDN calls
  • Confluence integration — push HTML reports via REST API

Installation

Path A — Pre-built binary (no Rust required)

bash install.sh    # Windows 10/11 (Git Bash) or Linux
bash run.sh        # http://127.0.0.1:4317

The script tries in order: existing binary → dist/ bundle → offline Rust build.

Transferable bundle: Run make bundle to produce oxide-sloc-bundle.tar.gz — drop it on a USB drive and run the install script on the target machine.

Path B — Docker

docker pull ghcr.io/nimashafie/oxide-sloc:latest
# or build locally
docker compose up
# CLI via Docker
docker run --rm -v /path/to/your/repo:/repo:ro \
  ghcr.io/nimashafie/oxide-sloc:latest analyze /repo --plain

See docs/airgap.md for air-gapped setup and docs/server-deployment.md for persistent deployments.


Usage

CLI

# Analyze and print a colored summary
oxide-sloc analyze ./my-repo

# Machine-readable key=value output
oxide-sloc analyze ./my-repo --plain

# Full output: JSON + HTML + CSV + Excel
oxide-sloc analyze ./my-repo -j result.json -H report.html -c report.csv -x report.xlsx

# Per-file breakdown in the terminal
oxide-sloc analyze ./my-repo --per-file

# Open the HTML report immediately after generation
oxide-sloc analyze ./my-repo -H report.html --open

# Quiet mode — only write files, print nothing (ideal for CI)
oxide-sloc analyze ./my-repo -j result.json --quiet

# Pipeline guards
oxide-sloc analyze ./my-repo --fail-on-warnings --fail-below 10000

# Filter by language or glob
oxide-sloc analyze ./my-repo --enabled-language rust --enabled-language python --plain
oxide-sloc analyze ./my-repo --include-glob "src/**" --exclude-glob "vendor/**"

# Git submodule breakdown
oxide-sloc analyze ./mono-repo --submodule-breakdown -j result.json -H report.html

# Re-render a report from saved JSON
oxide-sloc report result.json -H report.html --pdf-out report.pdf -c report.csv -x report.xlsx

# Compare two saved results
oxide-sloc diff baseline.json current.json
oxide-sloc diff baseline.json current.json -j delta.json -c delta.csv -x delta.xlsx

# Generate a starter config
oxide-sloc init                        # creates .oxide-sloc.toml
oxide-sloc init ci/sloc.toml --force

# Start the web UI
oxide-sloc serve              # http://127.0.0.1:4317, auto-opens browser
oxide-sloc serve --server     # binds to 0.0.0.0, no browser auto-open

# Deliver a saved report
oxide-sloc send result.json --smtp-to team@example.com --smtp-from bot@example.com --smtp-host smtp.example.com
oxide-sloc send result.json --webhook-url https://hooks.example.com/sloc --webhook-token "$TOKEN"

CLI flags reference

analyze

Flag Short Default Description
--json-out -j (none) Write JSON result
--html-out -H (none) Write HTML report
--csv-out -c (none) Write CSV summary
--xlsx-out -x (none) Write Excel workbook (4 sheets)
--pdf-out (none) Write PDF (requires Chrome/Edge/Brave)
--open off Open HTML in system browser
--quiet -q off Suppress all non-error output
--plain off Machine-readable key=value output
--per-file off Per-file breakdown in terminal
--fail-on-warnings off Exit 2 if warnings are emitted
--fail-below (none) Exit 3 if code lines fall below N
--mixed-line-policy code-only code-only | code-and-comment | comment-only | separate-mixed-category
--python-docstrings-as-code off Treat docstrings as code
--continuation-line-policy each-physical-line each-physical-line | collapse-to-logical — IEEE 1045-1992 §3
--blank-in-block-comment-policy count-as-comment count-as-comment | count-as-blank — IEEE 1045-1992 §4
--no-count-compiler-directives off Exclude #include/#define from code SLOC — IEEE 1045-1992 §4.2 (C/C++/ObjC only)
--include-glob (all) Only scan matching files (repeatable)
--exclude-glob (none) Skip matching files (repeatable)
--enabled-language (all) Restrict to language (repeatable)
--no-ignore-files off Ignore .gitignore / .ignore
--follow-symlinks off Follow symbolic links
--report-title folder name Title in HTML/PDF/XLSX reports
--submodule-breakdown off Per-submodule stats from .gitmodules
--config (none) Load settings from TOML file

report / diff / init / serve / send

Run oxide-sloc <command> --help for the full flag list of each subcommand.

Web UI

oxide-sloc serve   # → http://127.0.0.1:4317

A guided 4-step flow: select project → counting rules → outputs → review & run. The Quick Scan sidebar button submits from step 1 with all defaults.

Every web UI option maps 1:1 to a CLI flag — see the Web UI → CLI translation table below.

Configuration file

cp sloc.example.toml sloc.toml
oxide-sloc init    # or generate one with the CLI

CLI flags always override config file values.


Scan history and delta tracking

Every web UI scan is recorded in out/web/registry.json. Re-running the same project path shows an inline delta:

  • Lines added / removed / unchanged
  • Files modified / added / removed

Navigate to /history to browse past scans, or /compare?a=<run_id>&b=<run_id> for a side-by-side file-level diff with four chart types.


Symbol counting

oxide-sloc performs best-effort lexical detection of structural symbols across 10+ languages. Counts are surfaced in the JSON output (functions, classes, variables, imports fields) and in the HTML report.

Supported languages: C, C++, C#, Go, Java, JavaScript, Rust, Shell, PowerShell, TypeScript.


Counting methodology — IEEE 1045-1992

oxide-sloc implements physical SLOC as defined in IEEE Std 1045-1992 Software Productivity Metrics. Every source line is classified into one of four categories before any policy is applied:

Category What it contains
Code Executable statements, declarations, and compiler directives
Comment Lines consisting solely of comment text
Mixed Lines that contain both code and a trailing comment
Blank Empty or whitespace-only lines

The standard defines several counting parameters as configurable. oxide-sloc exposes all of them via CLI flags and the TOML config file.

Mixed-line policy — mixed_line_policy

Controls how lines that contain both code and a comment are counted toward the totals. Default: code-only.

Value Behaviour
code-only (default) Mixed lines count toward code only
code-and-comment Mixed lines are counted in both totals
comment-only Mixed lines count toward comments only
separate-mixed-category Mixed lines are kept in a separate total

Continuation-line policy — continuation_line_policy (IEEE 1045-1992 §3)

Controls how backslash-continued lines (C/C++ macros, shell, Makefile) are counted. Default: each-physical-line.

Value Behaviour
each-physical-line (default) Each physical line is counted separately (physical SLOC mode)
collapse-to-logical A backslash-continued sequence counts as a single logical line

Blank lines inside block comments — blank_in_block_comment_policy (IEEE 1045-1992 §4)

Controls how blank lines that fall inside /* ... */ (or equivalent) comment blocks are classified. Default: count-as-comment, which is the IEEE-aligned behaviour.

Value Behaviour
count-as-comment (default, IEEE aligned) Blank lines inside block comments count as comment lines
count-as-blank Blank lines inside block comments remain blank lines

Compiler directives — count_compiler_directives (IEEE 1045-1992 §4.2)

Applies to C, C++, and Objective-C only. By default, preprocessor directive lines (#include, #define, #ifdef, #pragma, etc.) are counted as code lines. Set count_compiler_directives = false to exclude them from effective code SLOC — they are still recorded in the raw JSON output as compiler_directive_lines so nothing is lost.

TOML configuration

All parameters are settable in .oxide-sloc.toml under [analysis]:

[analysis]
mixed_line_policy            = "code-only"          # code-only | code-and-comment | comment-only | separate-mixed-category
continuation_line_policy     = "each-physical-line"  # each-physical-line | collapse-to-logical
blank_in_block_comment_policy = "count-as-comment"  # count-as-comment | count-as-blank
count_compiler_directives    = true                 # false = exclude #include/#define from code SLOC (C/C++/ObjC)
python_docstrings_as_comments = true                # false = treat docstrings as code

Run oxide-sloc init to generate a starter config with all options documented inline.


Supported languages (41)

Language Extensions / Filenames Comment styles
Assembly .asm, .s ;
C .c, .h // /* */
C++ .cc, .cpp, .cxx, .hpp, .hxx // /* */
C# .cs // /* */ verbatim strings
Clojure .clj, .cljs, .cljc, .edn ;
CSS .css /* */
Dart .dart // /* */
Dockerfile Dockerfile, Dockerfile.* #
Elixir .ex, .exs #
Erlang .erl, .hrl %
F# .fs, .fsi, .fsx // (* *)
Go .go // /* */
Groovy .groovy, .gradle // /* */
Haskell .hs, .lhs -- {- -}
HTML .html, .htm, .xhtml <!-- -->
Java .java // /* */
JavaScript .js, .mjs, .cjs // /* */
Julia .jl # #= =#
Kotlin .kt, .kts // /* */
Lua .lua -- --[[ ]]
Makefile Makefile, GNUmakefile, .mk #
Nim .nim, .nims # #[ ]#
Objective-C .m, .mm // /* */
OCaml .ml, .mli (* *)
Perl .pl, .pm, .t #
PHP .php // # /* */
PowerShell .ps1, .psm1, .psd1 # <# #>
Python .py # docstrings
R .r #
Ruby .rb, .rake, Rakefile, Gemfile #
Rust .rs // /* */
Scala .scala, .sc // /* */
SCSS .scss, .sass // /* */
Shell .sh, .bash, .zsh, .ksh #
SQL .sql -- /* */
Svelte .svelte // /* */
Swift .swift // /* */
TypeScript .ts, .mts, .cts // /* */
Vue .vue // /* */
XML / SVG .xml, .xsd, .xsl, .svg <!-- -->
Zig .zig //

Not supported (intentionally): TOML, Markdown, YAML — no meaningful SLOC metric applies. Shebang (#!) detection works for Python, Shell, Ruby, Perl, PHP, and Node.js scripts.

Adding a new language

  1. crates/sloc-languages/src/lib.rs — add a Language variant, implement display_name/as_slug/from_name, register extensions in detect_language, add a ScanConfig entry in analyze_text.
  2. No change needed in sloc-configenabled_languages filtering picks up new variants automatically.

PDF export

PDF generation uses a locally installed Chromium-based browser (Chrome, Edge, Brave, Vivaldi, or Opera). Generation runs in the background; the web UI returns results immediately.

export SLOC_BROWSER=/usr/bin/chromium   # override browser path
oxide-sloc report result.json --pdf-out result.pdf

In Docker, Chromium is bundled — no extra setup needed.


CSV and Excel export

Every HTML report has Export CSV and Export Excel buttons in the nav bar. The Excel workbook contains four sheets: Summary, By Language, Per File, and Skipped Files — no plugins required, works in Excel, LibreOffice, and Google Sheets.

The same exports are available from the CLI:

oxide-sloc analyze ./my-repo -c result.csv -x result.xlsx
oxide-sloc report result.json -c result.csv -x result.xlsx
oxide-sloc diff baseline.json current.json -c delta.csv -x delta.xlsx

Metrics API

Endpoint Description
GET /api/metrics/latest Metrics for the most recent scan
GET /api/metrics/:run_id Metrics for a specific run
GET /api/project-history?path=<dir> Scan history for a project root
GET /badge/:metric SVG badge (code-lines, files, comment-lines, blank-lines)
GET /embed/summary Embeddable HTML widget
GET /healthz Health check
![Code Lines](http://your-host:4317/badge/code-lines)
<iframe src="http://your-host:4317/embed/summary" width="100%" height="180" frameborder="0"></iframe>

CI/CD

Web UI → CLI translation

Web UI CLI equivalent
Step 1: select project oxide-sloc analyze ./my-repo
Step 1: include / exclude pattern --include-glob / --exclude-glob
Step 1: submodule breakdown --submodule-breakdown
Quick Scan oxide-sloc analyze ./my-repo --plain
Step 2: mixed-line policy --mixed-line-policy code-only
Step 2: Python docstrings as code --python-docstrings-as-code
(config / CLI only) --continuation-line-policy collapse-to-logical
(config / CLI only) --blank-in-block-comment-policy count-as-blank
(config / CLI only) --no-count-compiler-directives
Step 3: outputs -j -H --pdf-out -c -x --open
Step 3: custom title --report-title "My Report"
Re-render from saved JSON oxide-sloc report result.json -H report.html
Compare two scans oxide-sloc diff baseline.json current.json
Generate starter config oxide-sloc init
Quiet / fail guards --quiet --fail-on-warnings --fail-below N

CI config presets

File Use case
ci/sloc-ci-default.toml Balanced defaults
ci/sloc-ci-strict.toml Fail-fast on binary files
ci/sloc-ci-full-scope.toml Audit mode — counts vendor/lockfiles too

GitHub Actions

Workflow Trigger What it does
ci.yml push to main, all PRs fmt → clippy → build → tests → CLI smoke → web health check
release.yml v* tag Cross-compile for 4 platforms → sign Windows binary → GitHub Release
docker.yml push to main, v* tag Build and push Docker image to GHCR

To cut a release:

git tag v1.1.0
git push origin v1.1.0

Jenkins / GitLab CI

A Jenkinsfile and .gitlab-ci.yml are included at the repo root. Both decompress vendor.tar.xz once per workspace and cache vendor/ between runs.

For detailed setup including Confluence publishing, see docs/ci-integrations.md.


Local development

# Run all CI gates before pushing
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo build --workspace
cargo test --workspace

# Run the web UI during development
cargo run -p oxide-sloc -- serve

# Fast rebuild (keeps vendored dep cache, ~1 min)
cargo clean -p oxide-sloc -p sloc-config -p sloc-core -p sloc-languages -p sloc-report -p sloc-web \
  && cargo run -p oxide-sloc -- serve

run.sh vs cargo run: When Rust is available, run.sh now prefers cargo run so changes are always picked up. During active development, either works.

Make targets (Linux/macOS):

make check        # fmt + lint + test
make dev          # fmt + lint + test + serve
make build        # release binary → target/release/oxide-sloc
make docker-build # build Docker image locally

Repository layout

crates/
  sloc-cli/         # CLI entry point and commands
  sloc-config/      # Config schema and TOML parsing
  sloc-core/        # File discovery, decoding, aggregation, delta engine
  sloc-languages/   # Language detection, lexical analyzers, symbol counting
  sloc-report/      # HTML rendering, PDF export, CSV/Excel export
  sloc-web/         # Axum web server, scan registry, metrics API, badge endpoint
dist/               # Pre-built binaries (used by run.sh / install.sh)
ci/                 # CI config presets (sloc.toml files)
deploy/             # systemd unit + server config template
docs/               # airgap, CI integrations, server deployment, licensing

License

oxide-sloc is licensed under AGPL-3.0-or-later. Copyright (C) 2026 Nima Shafie. All intellectual property rights vest solely in the author.

Commercial support, hosted services, and proprietary add-ons are available through separate arrangements. See docs/licensing-commercial.md.


Nima Shafiegithub.com/NimaShafie