summaryrefslogtreecommitdiff
path: root/scripts/count_assisted_by.sh
blob: 57cdf65d29ab896a9e7a05baf56cb2b22b0664a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#!/bin/bash
##############################################################################
# Copyright (C) 2026 Eclipse ThreadX contributors
#
# This program and the accompanying materials are made available under the
# terms of the MIT License which is available at
# https://opensource.org/licenses/MIT.
#
# AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5).
# The AI-generated portions may be considered public domain (CC0-1.0)
# and not subject to the project's licence. The human contributor has
# reviewed and verified that the code is correct.
#
# SPDX-License-Identifier: MIT and CC0-1.0
##############################################################################

# Report the Assisted-by attributions in a repository's history.
#
#     scripts/count_assisted_by.sh                     # HEAD, grouped by value
#     scripts/count_assisted_by.sh origin/dev          # a branch
#     scripts/count_assisted_by.sh origin/dev -- ports # a path
#     scripts/count_assisted_by.sh --list origin/dev   # one line per commit
#
# Why not git's own trailer parser: git reads trailers only from a block at the
# very end of a message. A squash merge concatenates the branch's commit
# messages, which leaves every trailer but the last one buried mid-message, and
# an indented trailer is skipped as well. Both forms are real attributions and
# both are invisible to --format='%(trailers:key=Assisted-by)'. This reads whole
# commit bodies instead, so the count is complete.

set -u

list=0
if [ "${1:-}" = "--list" ]; then
    list=1
    shift
fi

rev="${1:-}"
if [ -n "$rev" ] && [ "$rev" != "--" ]; then
    shift
else
    rev="HEAD"
fi

if [ "${1:-}" = "--" ]; then
    shift
fi

# %x02 opens a record and %x01 separates the hash from the body, so bodies
# containing blank lines survive the pass through awk.
git log "$rev" --format='%x02%H%x01%B' ${1+"$@"} \
 | tr '\n' '\003' | tr '\002' '\n' \
 | awk -F'\001' -v list="$list" '
     NF >= 2 {
         body = $2
         gsub(/\003/, "\n", body)
         n = split(body, line, "\n")
         for (i = 1; i <= n; i++) {
             if (line[i] ~ /^[[:space:]]*Assisted-by:[[:space:]]*/) {
                 value = line[i]
                 sub(/^[[:space:]]*Assisted-by:[[:space:]]*/, "", value)
                 sub(/[[:space:]]+$/, "", value)
                 if (value == "")
                     continue
                 if (list)
                     print substr($1, 1, 8) "  " value
                 else
                     count[value]++
             }
         }
     }
     END {
         if (list)
             exit
         for (value in count)
             printf "%6d  %s\n", count[value], value
     }' \
 | { if [ "$list" -eq 1 ]; then cat; else sort -rn; fi; }