Analyze Git commit activity by hour with member mapping and configurable outputs.
Project description
NightOwls
NightOwls is a Python CLI for analyzing Git commit activity by hour of day.
It supports:
- JSON analysis output
- stacked bar chart PNG output (x: hour, y: commit count, stacked by member)
- resolved config output
- bootstrapped members map output
Install
python -m pip install .
For development:
python -m pip install -r requirements.txt
Run
PYTHONPATH=src python -m nightowls --help
Or after install:
nightowls --help
Configuration Sources And Precedence
NightOwls merges configuration in this order:
- CLI options
-c /path/to/config.jsonnightowls.jsonin repository root- internal defaults
JSON Schema
Schema file in repo:
src/nightowls/schemas/nightowls.schema.json
Raw URL (for $schema):
https://raw.githubusercontent.com/5cover/nightowls/main/src/nightowls/schemas/nightowls.schema.json
Example header in nightowls.json:
{
"$schema": "https://raw.githubusercontent.com/5cover/nightowls/main/src/nightowls/schemas/nightowls.schema.json"
}
nightowls.json Format
{
"$schema": "https://raw.githubusercontent.com/5cover/nightowls/main/src/nightowls/schemas/nightowls.schema.json",
"timezone": "local",
"identity_source": "author",
"member_sort": "commit_count",
"output": {
"format": "json",
"path": null
},
"chart": {
"title": null
},
"filters": {
"since": null,
"until": null,
"branch": null,
"no_merges": false
},
"members": [
["Raphael", { "name": "Scover", "email": "thediscover22450@gmail.com" }],
["Romain", { "name": "Soladoc" }],
["Noreply", { "email": { "regex": "@users\\.noreply\\.github\\.com$" } }],
["Unknown", {}]
]
}
Members Mapping Semantics
members is an ordered list of pairs:
[member_name, matcher]
Rules:
- first match wins
matcher.nameandmatcher.emailare optional- missing or
nullmeans wildcard for that field - string value means exact match
{ "regex": "..." }means regex match- if nothing matches, NightOwls falls back to the git actor name
Member Ordering
member_sort controls member order in JSON output and chart stacking/color assignment.
"commit_count"(default): descending by total commit count, then alphabetical"alphabetical": ascending by member name["name1", "name2", ...]: custom order; members not listed are appended alphabetically
Chart Title Behavior
- If
chart.title(or--chart-title) is set, it is used. - Otherwise title is
Commits by hour (stacked by member) - {repo name}when repo name is available. - Final fallback is
Commits by hour (stacked by member).
CLI Options
nightowls [path]
-c, --config PATH
--timezone {local,utc}
--output-format {json,png,config,members}
--output-path PATH
--chart-title TEXT
--identity-source {author,committer}
--since EXPR
--until EXPR
--branch REV
--no-merges
Examples
JSON output:
nightowls . --output-format json
PNG output:
nightowls . --output-format png --output-path out.png
PNG output with custom title:
nightowls . --output-format png --chart-title "Night activity overview"
Resolved config output:
nightowls . --output-format config
Bootstrap members map:
nightowls . --output-format members > members.json
Use custom config:
nightowls . -c ./nightowls.json --output-format json
Build
python -m build
Publish To PyPI
- The
Publishworkflow runs on tags matchingv*(for examplev1.0.1). - Configure PyPI Trusted Publishing for this repository, then create and push a version tag:
git tag v1.0.1
git push origin v1.0.1
Test
PYTHONPATH=src python -m unittest discover -s tests -p 'test_*.py'
Project details
Release history Release notifications | RSS feed
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 nightowls-1.0.0.tar.gz.
File metadata
- Download URL: nightowls-1.0.0.tar.gz
- Upload date:
- Size: 14.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f53276a69988a903ad3e65cbf6acb27f15da9661c39eed05f353303ea953b8a
|
|
| MD5 |
7bcc4d1e6ee2bdd90fc416a72bbc36e4
|
|
| BLAKE2b-256 |
1efe47953093360f807ae0e876036884e6292908e51168e0fdf544027fcabdbd
|
Provenance
The following attestation bundles were made for nightowls-1.0.0.tar.gz:
Publisher:
publish.yml on 5cover/nightowls
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nightowls-1.0.0.tar.gz -
Subject digest:
7f53276a69988a903ad3e65cbf6acb27f15da9661c39eed05f353303ea953b8a - Sigstore transparency entry: 1271046201
- Sigstore integration time:
-
Permalink:
5cover/nightowls@b34a190f01678b9ba4e8c2d4785d2ae257c7aadc -
Branch / Tag:
refs/heads/main - Owner: https://github.com/5cover
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b34a190f01678b9ba4e8c2d4785d2ae257c7aadc -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file nightowls-1.0.0-py3-none-any.whl.
File metadata
- Download URL: nightowls-1.0.0-py3-none-any.whl
- Upload date:
- Size: 13.5 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 |
6aac425129510c0a8049a9fbc5d1e9866addb83335d80719e3de56ee8a192f93
|
|
| MD5 |
bdf7b081abc99eb477f2ecc832d1ab47
|
|
| BLAKE2b-256 |
5ecf3a8a6f5232699bc0db3abbd446620b23d29c3e0290e684c062ec2ef11958
|
Provenance
The following attestation bundles were made for nightowls-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on 5cover/nightowls
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nightowls-1.0.0-py3-none-any.whl -
Subject digest:
6aac425129510c0a8049a9fbc5d1e9866addb83335d80719e3de56ee8a192f93 - Sigstore transparency entry: 1271046244
- Sigstore integration time:
-
Permalink:
5cover/nightowls@b34a190f01678b9ba4e8c2d4785d2ae257c7aadc -
Branch / Tag:
refs/heads/main - Owner: https://github.com/5cover
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b34a190f01678b9ba4e8c2d4785d2ae257c7aadc -
Trigger Event:
workflow_dispatch
-
Statement type: