Ignore generic metadata files in counts
ci / test (push) Successful in 9s

This commit is contained in:
2026-07-16 20:36:06 +00:00
parent 0ccd4e47ae
commit ecc1578b92
4 changed files with 81 additions and 0 deletions
+7
View File
@@ -8,6 +8,7 @@ Tiny API that clones a Git repo and counts its non-empty lines of code.
- 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
@@ -66,6 +67,12 @@ curl "http://localhost:3000/ssh/public-key?ssh_key=loc_via_git_ed25519"
- 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:
+57
View File
@@ -0,0 +1,57 @@
import path from "node:path";
const ignoredFileNames = new Set([
".editorconfig",
".gitattributes",
".gitignore",
".gitmodules",
".npmrc",
".nvmrc",
".prettierignore",
".prettierrc",
".prettierrc.json",
".yarnrc",
".yarnrc.yml",
"bun.lock",
"bun.lockb",
"cargo.lock",
"composer.json",
"composer.lock",
"deno.json",
"deno.lock",
"docker-compose.yaml",
"docker-compose.yml",
"eslint.config.js",
"eslint.config.mjs",
"global.json",
"go.mod",
"go.sum",
"gradle.properties",
"makefile",
"package-lock.json",
"package.json",
"pnpm-lock.yaml",
"poetry.lock",
"pom.xml",
"requirements.txt",
"rollup.config.js",
"rollup.config.mjs",
"settings.gradle",
"settings.gradle.kts",
"tsconfig.base.json",
"tsconfig.build.json",
"tsconfig.json",
"tsconfig.node.json",
"turbo.json",
"vite.config.js",
"vite.config.mjs",
"vite.config.ts",
"webpack.config.js",
"webpack.config.ts",
"yarn.lock"
]);
export function shouldIgnoreCountFile(filePath: string): boolean {
const fileName = path.basename(filePath).toLowerCase();
return ignoredFileNames.has(fileName);
}
+5
View File
@@ -5,6 +5,7 @@ import path from "node:path";
import type { RuntimeConfig } from "../config.js";
import { HttpError } from "../errors.js";
import { shouldIgnoreCountFile } from "../file-filter.js";
import { detectLanguage } from "../language.js";
import { Semaphore } from "../lib/semaphore.js";
import type { CountRequest, CountResult, LanguageStat } from "../types.js";
@@ -183,6 +184,10 @@ async function countDirectory(rootDir: string): Promise<{
continue;
}
if (shouldIgnoreCountFile(fullPath)) {
continue;
}
const lines = await countFileLines(fullPath);
const language = detectLanguage(fullPath);
const current = languages.get(language) ?? { language, files: 0, lines: 0 };
+12
View File
@@ -0,0 +1,12 @@
import test from "node:test";
import assert from "node:assert/strict";
import { shouldIgnoreCountFile } from "../dist/file-filter.js";
test("shouldIgnoreCountFile skips generic project metadata files", () => {
assert.equal(shouldIgnoreCountFile("/tmp/package.json"), true);
assert.equal(shouldIgnoreCountFile("/tmp/tsconfig.json"), true);
assert.equal(shouldIgnoreCountFile("/tmp/docker-compose.yml"), true);
assert.equal(shouldIgnoreCountFile("/tmp/src/index.ts"), false);
assert.equal(shouldIgnoreCountFile("/tmp/README.md"), false);
});