gitlogstats 1.5.0__tar.gz → 1.5.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/PKG-INFO +1 -1
  2. gitlogstats-1.5.1/docs/examples/README.md +70 -0
  3. gitlogstats-1.5.1/docs/examples/assignment-stats.sh +113 -0
  4. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/pyproject.toml +1 -1
  5. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/.claude/CLAUDE.md +0 -0
  6. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/.claude/agents/developer-agent.md +0 -0
  7. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/.claude/agents/spec-reviewer.md +0 -0
  8. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/.claude/hooks/format-edited.sh +0 -0
  9. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/.claude/hooks/guard-paths.sh +0 -0
  10. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/.claude/hooks/guard-paths.test.mjs +0 -0
  11. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/.claude/hooks/verify.sh +0 -0
  12. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/.claude/settings.json +0 -0
  13. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/.claude/skills/phase-handoff/SKILL.md +0 -0
  14. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/.claude/skills/stale-check/SKILL.md +0 -0
  15. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/.github/workflows/build.yaml +0 -0
  16. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/.gitignore +0 -0
  17. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/.prettierrc.json +0 -0
  18. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/LICENSE +0 -0
  19. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/Pipfile +0 -0
  20. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/Pipfile.lock +0 -0
  21. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/README.md +0 -0
  22. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/docs/SPEC.md +0 -0
  23. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/package-lock.json +0 -0
  24. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/package.json +0 -0
  25. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/repos.txt +0 -0
  26. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/requirements.txt +0 -0
  27. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/scripts/board/config.mjs +0 -0
  28. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/scripts/board/derive.mjs +0 -0
  29. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/scripts/board/derive.test.mjs +0 -0
  30. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/scripts/board/manifest.yaml +0 -0
  31. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/scripts/board/sync.mjs +0 -0
  32. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/src/gitlogstats/__init__.py +0 -0
  33. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/src/gitlogstats/__main__.py +0 -0
  34. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/src/gitlogstats/clones.py +0 -0
  35. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/src/gitlogstats/git_logs_parser.py +0 -0
  36. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/src/gitlogstats/github.py +0 -0
  37. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/src/gitlogstats/github_stats.py +0 -0
  38. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/src/gitlogstats/identity.py +0 -0
  39. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/tests/fake_gh.py +0 -0
  40. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/tests/fixtures/github/commit_linked.json +0 -0
  41. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/tests/fixtures/github/commit_unlinked.json +0 -0
  42. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/tests/fixtures/github/contributors.json +0 -0
  43. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/tests/fixtures/github/contributors_page2.json +0 -0
  44. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/tests/fixtures/github/pulls_page1.json +0 -0
  45. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/tests/fixtures/github/pulls_page2.json +0 -0
  46. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/tests/fixtures/github/user_full.json +0 -0
  47. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/tests/fixtures/github/user_private.json +0 -0
  48. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/tests/test_clobber.py +0 -0
  49. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/tests/test_git_logs_parser.py +0 -0
  50. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/tests/test_github.py +0 -0
  51. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/tests/test_identity.py +0 -0
  52. {gitlogstats-1.5.0 → gitlogstats-1.5.1}/tests/test_integration.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: gitlogstats
3
- Version: 1.5.0
3
+ Version: 1.5.1
4
4
  Summary: Track developers' contributions to one or more git repositories within a particular time range.
5
5
  Project-URL: Homepage, https://github.com/bloombar/gitlogstats
6
6
  Project-URL: Repository, https://github.com/bloombar/gitlogstats.git
@@ -0,0 +1,70 @@
1
+ # Examples
2
+
3
+ ## `assignment-stats.sh`: statistics for one assignment
4
+
5
+ Reports every student's contributions to one assignment: all the repositories in a GitHub organization whose names start with the same prefix (e.g. `web-app-exercise-`), over a date range. It works in bash on macOS, Linux, WSL and Git Bash on Windows.
6
+
7
+ ### Requirements
8
+
9
+ - Python 3
10
+ - git
11
+ - The [GitHub CLI](https://cli.github.com) (`gh`), signed in with `gh auth login`
12
+
13
+ You don't need to install `gitlogstats` yourself: the script installs or upgrades it each time it runs (see [What the script does](#what-the-script-does)).
14
+
15
+ ### Usage
16
+
17
+ ```bash
18
+ ./assignment-stats.sh ORGANIZATION_NAME REPO_PREFIX START_DATE END_DATE [gitlogstats options...]
19
+ ```
20
+
21
+ | Argument | Meaning | Example |
22
+ | ------------------- | ---------------------------------------------------------------------- | ---------------------------- |
23
+ | `ORGANIZATION_NAME` | The GitHub organization that holds the students' repositories | `software-students-fall2029` |
24
+ | `REPO_PREFIX` | The start of the repository names for this assignment | `web-app-exercise-` |
25
+ | `START_DATE` | First day of the period, `mm/dd/yyyy` | `09/01/2029` |
26
+ | `END_DATE` | Last day of the period, `mm/dd/yyyy` (included) | `10/16/2029` |
27
+ | options | Anything after the four arguments is passed to `gitlogstats` unchanged | `--github -f markdown` |
28
+
29
+ Run it from any directory. The results are printed to standard output, so redirect them to save them; progress messages go to standard error and stay on screen.
30
+
31
+ ### Examples
32
+
33
+ Save a CSV of one assignment's statistics:
34
+
35
+ ```bash
36
+ ./assignment-stats.sh software-students-fall2029 web-app-exercise- 09/01/2029 10/16/2029 > web-app-exercise.csv
37
+ ```
38
+
39
+ Include the GitHub columns (pull requests, pushes, website commits, emails) and print a Markdown table:
40
+
41
+ ```bash
42
+ ./assignment-stats.sh software-students-fall2029 web-app-exercise- 09/01/2029 10/16/2029 --github -f markdown
43
+ ```
44
+
45
+ Leave out students with no activity in the period, as JSON:
46
+
47
+ ```bash
48
+ ./assignment-stats.sh software-students-fall2029 web-app-exercise- 09/01/2029 10/16/2029 -c -f json > web-app-exercise.json
49
+ ```
50
+
51
+ To run it from elsewhere, give its path, e.g. `bash docs/examples/assignment-stats.sh ...`. On Windows, run it from Git Bash or WSL, not from Command Prompt or PowerShell.
52
+
53
+ See the main [README](../../README.md) for every `gitlogstats` option and what each column means.
54
+
55
+ ### What the script does
56
+
57
+ 1. Checks the arguments and that Python, git and `gh` are installed and `gh` is signed in. If anything is missing it stops with a message saying what.
58
+ 2. Installs or upgrades `gitlogstats` in a Python environment of its own, `~/.gitlogstats-venv`, reused by later runs. Set `GITLOGSTATS_VENV` to keep it elsewhere. A separate environment is needed because Homebrew Python and recent Debian and Ubuntu releases refuse a system-wide `pip install`.
59
+ 3. Lists the organization's repositories whose names start with `REPO_PREFIX`, into a temporary file that is deleted when the script ends, even after an error. An existing `repos.txt` in your directory is never touched. If no repository matches, it stops with an error.
60
+ 4. Runs `gitlogstats` on those repositories with `--clobber`, so the clones it makes in `./repos/` are deleted once the results are printed.
61
+
62
+ ### Troubleshooting
63
+
64
+ | Message | What to do |
65
+ | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
66
+ | `'...' is not a date in mm/dd/yyyy format` | Write dates with two-digit month and day and a four-digit year, e.g. `09/01/2029` |
67
+ | `the GitHub CLI is not signed in` | Run `gh auth login` |
68
+ | `no repositories in '...' start with '...'` | Check the organization name and prefix; the prefix is case-sensitive |
69
+ | `could not create a virtual environment` | On Debian or Ubuntu, install the venv module: `sudo apt install python3-venv` |
70
+ | `Permission denied` when running `./assignment-stats.sh` | Make it executable with `chmod +x assignment-stats.sh`, or run it with `bash assignment-stats.sh ...` |
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Report every student's contributions to one assignment: all repositories in
4
+ # a GitHub organization whose names start with a given prefix, over a date
5
+ # range. Works in bash on macOS, Linux, other Unix systems, WSL and Git Bash.
6
+ #
7
+ # Usage:
8
+ # ./assignment-stats.sh ORGANIZATION_NAME REPO_PREFIX START_DATE END_DATE [gitlogstats options...]
9
+ #
10
+ # Example:
11
+ # ./assignment-stats.sh software-students-fall2029 web-app-exercise- 09/01/2029 10/16/2029 > stats.csv
12
+ # ./assignment-stats.sh software-students-fall2029 web-app-exercise- 09/01/2029 10/16/2029 --github -f markdown
13
+ #
14
+ # Dates are mm/dd/yyyy and both days are included. Any options after the four
15
+ # arguments are passed to gitlogstats unchanged (e.g. --github, -f json, -c).
16
+ # The results go to standard output; progress messages go to standard error.
17
+ #
18
+ # Requires: Python 3, git, and the GitHub CLI (gh), signed in with
19
+ # `gh auth login` (gh is used to list the organization's repositories).
20
+ # gitlogstats is installed or upgraded automatically in its own Python
21
+ # environment (~/.gitlogstats-venv, or $GITLOGSTATS_VENV).
22
+
23
+ set -euo pipefail
24
+
25
+ usage() {
26
+ echo "usage: $(basename "$0") ORGANIZATION_NAME REPO_PREFIX START_DATE END_DATE [gitlogstats options...]" >&2
27
+ echo "example: $(basename "$0") software-students-fall2029 web-app-exercise- 09/01/2029 10/16/2029" >&2
28
+ }
29
+
30
+ if [ "$#" -lt 4 ]; then
31
+ usage
32
+ exit 2
33
+ fi
34
+
35
+ # retrieve command-line arguments
36
+ ORGANIZATION_NAME=$1
37
+ REPO_PREFIX=$2
38
+ START_DATE=$3
39
+ END_DATE=$4
40
+ shift 4 # anything left is passed to gitlogstats
41
+
42
+ # check the dates before doing any work
43
+ for date in "$START_DATE" "$END_DATE"; do
44
+ if ! [[ "$date" =~ ^[0-9]{2}/[0-9]{2}/[0-9]{4}$ ]]; then
45
+ echo "error: '$date' is not a date in mm/dd/yyyy format" >&2
46
+ usage
47
+ exit 2
48
+ fi
49
+ done
50
+
51
+ # find a Python 3 interpreter: python3 on macOS and Linux, often python on Git Bash
52
+ if command -v python3 >/dev/null 2>&1; then
53
+ PYTHON=python3
54
+ elif command -v python >/dev/null 2>&1; then
55
+ PYTHON=python
56
+ else
57
+ echo "error: Python 3 is not installed" >&2
58
+ exit 1
59
+ fi
60
+
61
+ for tool in git gh; do
62
+ if ! command -v "$tool" >/dev/null 2>&1; then
63
+ echo "error: '$tool' is not installed" >&2
64
+ exit 1
65
+ fi
66
+ done
67
+
68
+ if ! gh auth status >/dev/null 2>&1; then
69
+ echo "error: the GitHub CLI is not signed in; run 'gh auth login' first" >&2
70
+ exit 1
71
+ fi
72
+
73
+ # install or upgrade gitlogstats in a virtual environment of its own: many
74
+ # systems (Homebrew Python, recent Debian and Ubuntu) refuse a system-wide
75
+ # pip install. The environment is kept and reused by later runs; set
76
+ # GITLOGSTATS_VENV to put it somewhere else.
77
+ VENV=${GITLOGSTATS_VENV:-"$HOME/.gitlogstats-venv"}
78
+ if [ ! -d "$VENV" ]; then
79
+ echo "Creating a Python environment for gitlogstats in $VENV..." >&2
80
+ if ! "$PYTHON" -m venv "$VENV"; then
81
+ echo "error: could not create a virtual environment (on Debian or Ubuntu, install python3-venv)" >&2
82
+ exit 1
83
+ fi
84
+ fi
85
+ # the environment's Python is in bin/ on macOS, Linux and WSL, Scripts/ on Windows
86
+ if [ -x "$VENV/bin/python" ]; then
87
+ VENV_PYTHON="$VENV/bin/python"
88
+ else
89
+ VENV_PYTHON="$VENV/Scripts/python.exe"
90
+ fi
91
+ echo "Installing the latest gitlogstats..." >&2
92
+ "$VENV_PYTHON" -m pip install --quiet --disable-pip-version-check --upgrade gitlogstats >&2
93
+
94
+ # list the assignment's repositories in a temporary file, so an existing
95
+ # repos.txt in this directory is never overwritten
96
+ REPOS_FILE=$(mktemp "${TMPDIR:-/tmp}/gitlogstats-repos.XXXXXX")
97
+ trap 'rm -f "$REPOS_FILE"' EXIT
98
+
99
+ # the prefix is read by gh's built-in jq from an environment variable, so it
100
+ # needs no quoting and jq does not have to be installed
101
+ REPO_PREFIX="$REPO_PREFIX" gh repo list "$ORGANIZATION_NAME" --limit 1000 \
102
+ --json name,url \
103
+ --jq '.[] | select(.name | startswith(env.REPO_PREFIX)) | .url' >"$REPOS_FILE"
104
+
105
+ count=$(grep -c . "$REPOS_FILE" || true)
106
+ if [ "$count" -eq 0 ]; then
107
+ echo "error: no repositories in '$ORGANIZATION_NAME' start with '$REPO_PREFIX'" >&2
108
+ exit 1
109
+ fi
110
+ echo "Analyzing $count repositories from $START_DATE to $END_DATE..." >&2
111
+
112
+ # --clobber deletes the clones once the results are printed
113
+ "$VENV_PYTHON" -m gitlogstats -rf "$REPOS_FILE" -s "$START_DATE" -e "$END_DATE" --clobber "$@"
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
5
5
  [project]
6
6
  name = "gitlogstats"
7
7
  description = "Track developers' contributions to one or more git repositories within a particular time range."
8
- version = "1.5.0"
8
+ version = "1.5.1"
9
9
  authors = [
10
10
  { name="Tobody Tothing", email="nobody.nothing@nowhere.com" },
11
11
  ]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes