A library for extracting metadata out of a source repository.
Project description
repo-parser
This is a set of python scripts and tools for extracting metadata and structure out of a monorepo, for the purposes of generating a service registry, unified documentation, or other types of data out of the contents.
It should be considered an experiment, rather than production software. It is inspired by my experiences in the software industry and being frustrated with current solutions being some combination of:
- Time consuming to configure and maintain
- Requiring the specification of redundant metadata (which is bound to get out of date)
Current assumptions:
- The files you want to process fit into memory
- You don't care about history (repo-parser gives a snapshot in time)
You can see a demo of a documentation site generated from this repo at:
https://repo-parser-demo.netlify.app/
Usage
For documentation generation and metadata extraction, see the example in example/example_parser.py.
An early version of repo-parser is available on pypi as https://pypi.org/project/repo-parser. Use at your own risk!
DuckDB Serialization
repo-parser can serialize the extracted metadata to a DuckDB database file, enabling:
- Queryable artifacts: Use SQL to query repository metadata without re-scanning
- Data composition: Join with external data sources (deployments, incidents, ownership)
- Language-agnostic consumption: Any tool with DuckDB bindings can use the data
- Portable artifacts: Share, cache, or version the database file
Basic Usage
import duckdb
from repo_parser import scan, get_resources
from repo_parser.outputs import to_duckdb
# Scan repository and extract metadata
dir, repo = scan("/path/to/repo", processors)
root_resource = get_resources(repo, dir, processors)
# Write resources into an in-memory DuckDB connection for augmentation/querying
con = duckdb.connect()
to_duckdb(con, root_resource)
# Or use a file-backed connection if you want to persist the table
con = duckdb.connect("repo.duckdb")
to_duckdb(con, root_resource)
con.close()
Schema
to_duckdb() creates one provisional table:
resources table - Flattened resource tree:
| Column | Type | Description |
|---|---|---|
path |
VARCHAR | Primary key: source path relative to the scanned root, . for root resource |
parent_path |
VARCHAR | Foreign key to parent resource path, NULL for root |
name |
VARCHAR | Resource name (e.g., "auth-service", "README.md") |
type |
VARCHAR | Resource type: 'repo', 'language', 'service', 'library', 'file' |
content |
TEXT | File content (NULL for non-file resources) |
properties |
JSON | Metadata/properties extracted by processors |
last_modified |
TIMESTAMP | Last modification time from git |
The example documentation build uses to_duckdb(..., table_name="resources_raw")
and also writes a SQL-derived resources_derived table used by the docs
renderer. The queries below assume the default resources table created by
plain to_duckdb(con, root_resource).
Example Queries
Find all services:
SELECT name, last_modified
FROM resources
WHERE type = 'service'
ORDER BY last_modified DESC;
Services missing READMEs:
SELECT name
FROM resources
WHERE type = 'service'
AND path NOT IN (
SELECT parent_path
FROM resources
WHERE name = 'README.md'
);
Get metadata for a specific service:
SELECT properties
FROM resources
WHERE name = 'auth-service' AND type = 'service';
Reconstruct tree hierarchy:
WITH RECURSIVE tree AS (
-- Start with root
SELECT path, parent_path, name, 0 as level
FROM resources
WHERE parent_path IS NULL
UNION ALL
-- Recursively get children
SELECT r.path, r.parent_path, r.name, t.level + 1
FROM resources r
JOIN tree t ON r.parent_path = t.path
)
SELECT repeat(' ', level) || name as tree_view
FROM tree
ORDER BY path;
Data Composition
Join repo-parser data with external sources:
import duckdb
con = duckdb.connect('repo.duckdb')
# Load external ownership data
con.execute("""
CREATE TABLE code_ownership AS
SELECT service_name, owner, team
FROM read_csv('codeowners.csv')
""")
# Find services without owners
result = con.execute("""
SELECT r.name, r.last_modified
FROM resources r
LEFT JOIN code_ownership co ON r.name = co.service_name
WHERE r.type = 'service' AND co.owner IS NULL
ORDER BY r.last_modified DESC
""").fetchall()
Common composition patterns:
- Deployment tracking: Join with deployment history to find undeployed changes
- Incident correlation: Link services to incidents to identify reliability issues
- Ownership mapping: Combine with CODEOWNERS or team databases
- Metrics enrichment: Add performance metrics, error rates, etc.
Querying from Command Line
# Direct SQL queries
duckdb repo.duckdb "SELECT name FROM resources WHERE type='service'"
# Export to CSV
duckdb repo.duckdb "COPY (SELECT * FROM resources) TO 'resources.csv' (HEADER)"
# Export to JSON
duckdb repo.duckdb "COPY (SELECT * FROM resources) TO 'resources.json'"
# Export to Parquet (for data pipelines)
duckdb repo.duckdb "COPY (SELECT * FROM resources) TO 'resources.parquet'"
Local development
You can experiment with the local demo by running make example.
It should live-reload as you make changes in the example/repo directory.
For other tasks, look at the (very simple) Makefile in the root directory.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file repo_parser-0.0.6.tar.gz.
File metadata
- Download URL: repo_parser-0.0.6.tar.gz
- Upload date:
- Size: 11.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
97b1c4007deb415d1014c04088365dc2403b106ae066f00724ed0061fa86ed68
|
|
| MD5 |
81d30959121076acdb75c8a47ce8b6c9
|
|
| BLAKE2b-256 |
6beaac5c46a19b2410be29b66c66d1743250dfff83666c7508b001809af41eed
|
Provenance
The following attestation bundles were made for repo_parser-0.0.6.tar.gz:
Publisher:
publish-to-pypi.yml on wlach/repo-parser
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
repo_parser-0.0.6.tar.gz -
Subject digest:
97b1c4007deb415d1014c04088365dc2403b106ae066f00724ed0061fa86ed68 - Sigstore transparency entry: 2195710516
- Sigstore integration time:
-
Permalink:
wlach/repo-parser@dded93d54d618ec56dab47eadb9766e99cbd9cc6 -
Branch / Tag:
refs/tags/0.0.6 - Owner: https://github.com/wlach
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@dded93d54d618ec56dab47eadb9766e99cbd9cc6 -
Trigger Event:
release
-
Statement type:
File details
Details for the file repo_parser-0.0.6-py3-none-any.whl.
File metadata
- Download URL: repo_parser-0.0.6-py3-none-any.whl
- Upload date:
- Size: 11.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
380f50437b85a1c47ea3dabe745c9e7e6421ae46d3f9716e59957821461e344c
|
|
| MD5 |
fc15297c63c4af7e2ceee26a7542dce1
|
|
| BLAKE2b-256 |
7dcebcd142e206a23585ebbad9de613e5abfae6bbaa34fc89b449c9a3ffcdff7
|
Provenance
The following attestation bundles were made for repo_parser-0.0.6-py3-none-any.whl:
Publisher:
publish-to-pypi.yml on wlach/repo-parser
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
repo_parser-0.0.6-py3-none-any.whl -
Subject digest:
380f50437b85a1c47ea3dabe745c9e7e6421ae46d3f9716e59957821461e344c - Sigstore transparency entry: 2195710518
- Sigstore integration time:
-
Permalink:
wlach/repo-parser@dded93d54d618ec56dab47eadb9766e99cbd9cc6 -
Branch / Tag:
refs/tags/0.0.6 - Owner: https://github.com/wlach
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@dded93d54d618ec56dab47eadb9766e99cbd9cc6 -
Trigger Event:
release
-
Statement type: