3.1 KiB
3.1 KiB
loc-via-git
Tiny API that clones a Git repo and counts its non-empty lines of code.
Features
- Plain text and JSON endpoints
- Optional API key enforcement
- Per-repo in-memory caching
- Extension-based language breakdown
- Generic project metadata files are ignored during counting
- Basic rate limiting
- Bounded concurrent scans so the host does not get hammered
- SSH key file support for private repos
- Docker Compose deployment
Endpoints
GET /loc.txt?repo=<git-url>&ssh_key=<optional-key-file>&ref=<optional-ref>&api_key=<optional-api-key>- Returns the line count as plain text.
GET /loc?repo=<git-url>&ssh_key=<optional-key-file>&ref=<optional-ref>&api_key=<optional-api-key>- Returns JSON metadata, including a language breakdown by files and non-empty lines.
GET /health- Health plus queue/cache stats.
Auth
No auth by default. If API_KEY is set, send it as either:
x-api-key: ...Authorization: Bearer ...api_key=...query param
The api_key query param is unsafe and discouraged because it can leak through logs, browser history, analytics, caches, and referrers.
Prefer x-api-key or Authorization whenever possible.
SSH keys
SSH keys live inside the Docker volume mounted at /app/keys, not in the repo or a host bind mount.
You have two options:
- Provide a key pair yourself inside the
ssh_keysDocker volume - Let the service generate the default key by setting
GENERATE_SSH_KEY_IF_MISSING=true
Example:
curl "http://localhost:3000/loc?repo=ssh://git@example.com/org/repo.git&ssh_key=loc_via_git_ed25519"
Fetch the public key to add it on the Git host:
curl http://localhost:3000/ssh/public-key
You can also request a specific key:
curl "http://localhost:3000/ssh/public-key?ssh_key=loc_via_git_ed25519"
Cleanup and caching
- Every clone happens in a temporary directory and is deleted in a
finallyblock after the scan finishes or fails. - The service also sweeps stale temp directories in case a process dies mid-scan.
- Cache entries live in memory only and expire after
CACHE_TTL_MINUTES.
Counting rules
- Only text files are counted.
- Empty lines are ignored.
- Generic project metadata files are skipped with a filename blacklist, for example
package.json, lockfiles,tsconfig.json, and similar config/build files.
Configuration
Copy .env.example to .env and adjust:
PORT=3000
API_KEY=
CACHE_TTL_MINUTES=5
CACHE_SWEEP_INTERVAL_MINUTES=5
RATE_LIMIT_WINDOW_MINUTES=5
RATE_LIMIT_MAX=30
MAX_CONCURRENT_SCANS=4
CLONE_TIMEOUT_SECONDS=45
DEFAULT_SSH_KEY_NAME=loc_via_git_ed25519
GENERATE_SSH_KEY_IF_MISSING=false
TRUST_PROXY=false
SSH_KEYS_DIR=/app/keys
TMP_DIR=/tmp/loc-via-git
Local run
npm install
npm run build
npm start
Docker compose
docker compose up --build
To copy an existing key pair into the Docker volume:
docker cp ./id_ed25519 loc-via-git-api-1:/app/keys/loc_via_git_ed25519
docker cp ./id_ed25519.pub loc-via-git-api-1:/app/keys/loc_via_git_ed25519.pub
Smoke test
npm run smoke