How to Recursively List Files in GeoLibre: 3 Methods for the Monorepo
To recursively list files in GeoLibre, use git ls-files for version-controlled files, find for directory traversal, or a custom Node.js walker for formatted tree output.
GeoLibre is a large monorepo maintained by opengeos that spans TypeScript/JavaScript workspaces, a Python backend, Rust components, and extensive test suites. Whether you need a quick file inventory or a hierarchical tree view, these three approaches cover every scenario.
Method 1: Git ls-files for Tracked Files
The fastest way to enumerate every version-controlled file uses Git's built-in plumbing command:
git ls-files
This scans the entire repository index—covering apps/, packages/, workers/, backend/, python/, and all other workspaces—without touching the working directory. For filenames containing spaces, add the -z flag for NUL-separated output safe for scripting:
git ls-files -z
Why this works for GeoLibre: The package.json at the repository root defines workspace globs (apps/*, packages/*, workers/*), but Git's index already contains every tracked path regardless of workspace boundaries.
Method 2: Find Command for Directory Trees
When you need a tree-like visualization without dependencies, combine find with sed:
find . -type f | sed 's|[^/]*/|│ |g; s|│ \([^│]*\)$|├── \1|'
This produces a hierarchical display by manipulating path separators. The command works on any fresh clone without requiring Git history access.
Limitation: This includes untracked files and respects .gitignore only if combined with Git. For a cleaner list, pipe through git check-ignore --stdin to filter ignored paths.
Method 3: Node.js Recursive Walker
For programmatic access with formatted output, use this scripts/list-files.js implementation that leverages Node.js fs/promises:
// file: scripts/list-files.js
import { readdir, stat } from 'node:fs/promises';
import { join } from 'node:path';
async function walk(dir, prefix = '') {
const entries = await readdir(dir, { withFileTypes: true });
for (const [i, entry] of entries.entries()) {
const isLast = i === entries.length - 1;
const connector = isLast ? '└─ ' : '├─ ';
console.log(prefix + connector + entry.name);
if (entry.isDirectory()) {
const newPrefix = prefix + (isLast ? ' ' : '│ ');
await walk(join(dir, entry.name), newPrefix);
}
}
}
await walk(process.cwd());
Execute from the repository root:
node scripts/list-files.js
When to use this: Build scripts, CI pipelines, or custom tooling that needs to process files while displaying progress. The withFileTypes: true option distinguishes files from directories without additional stat calls.
Key Files to Know in GeoLibre
These paths represent the repository's structural boundaries—each appears in recursive file listings:
| File | Role in File Enumeration |
|---|---|
README.md |
Documents high-level layout and entry points |
package.json |
Defines workspace roots that expand the file tree |
backend/geolibre_server/pyproject.toml |
Python side-car project, tracked alongside JS workspaces |
apps/geolibre-desktop/src-tauri/Cargo.toml |
Rust component demonstrating cross-language monorepo structure |
tests/ |
Extensive test suite recursively included in all listing methods |
Method Comparison
| Approach | Speed | Includes Untracked | Tree Output | Best For |
|---|---|---|---|---|
git ls-files |
Fastest | No | No | CI manifests, build scripts |
find + sed |
Fast | Yes | Yes | Quick terminal visualization |
| Node.js walker | Moderate | Configurable | Yes | Custom tooling, filtering |
Summary
git ls-files— fastest for version-controlled inventory across GeoLibre's monorepo workspacesfind . -type f— portable directory traversal with optional formatting viased- Custom Node.js walker — programmatic control for scripts requiring
readdirwithwithFileTypes
All three correctly traverse the mixed-language structure spanning TypeScript workspaces in apps/ and packages/, the Python backend in backend/geolibre_server/, and Rust components like apps/geolibre-desktop/src-tauri/.
Frequently Asked Questions
Does git ls-files include files in all GeoLibre workspaces?
Yes. git ls-files reads the Git index directly, so it captures every tracked file regardless of workspace configuration in package.json. This includes apps/*, packages/*, workers/*, and the Python backend.
How do I exclude node_modules from recursive file listings?
git ls-files automatically excludes node_modules because directories listed in .gitignore are untracked. For find, add -not -path '*/node_modules/*' before the | sed pipe.
Can I filter files by extension when listing recursively?
With git ls-files, append a pathspec: git ls-files '*.ts' '*.py'. For the Node.js walker, add an if (!entry.name.endsWith('.ts')) continue check before the console.log call.
What's the performance difference between这些方法?
git ls-files operates on the index in milliseconds even for repositories with 10,000+ files. find scales linearly with disk I/O. The Node.js walker adds Promise overhead but remains efficient for typical GeoLibre sizes (under one second for the full tree).
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →