- #!/bin/sh
- ############################################################ IDENT(1)
- #
- # $Title: Script to count perforce user commits by-year $
- #
- ############################################################ GLOBALS
- pgm="${0##*/}" # Program basename
- #
- # Global exit status
- #
- SUCCESS=0
- FAILURE=1
- #
- # Command-line options
- #
- NOHEADER= # -H
- ONELINE= # -1
- PAST365= # -Y
- REVERSE= # -r
- VERBOSE= # -v
- YEARS= # -y years
- #
- # Miscellaneous
- #
- NEWESTYEAR=
- OLDESTYEAR=
- USER_YEARS=
- THIS_YEAR=$( date +%Y )
- RANGE365=$( date +"@%m/%d/$(( $THIS_YEAR - 1 )),@now" )
- ############################################################ FUNCTIONS
- usage()
- {
- local fmt="$1"
- exec >&2
- if [ "$fmt" ]; then
- shift 1 # fmt
- printf "$pgm: $fmt\n" "$@"
- fi
- local optfmt="\t%-9s %s\n"
- printf "Usage: %s [OPTIONS] [user ...]\n" "$pgm"
- printf "OPTIONS:\n"
- printf "$optfmt" -1 "Output data as a single-line for each user/year."
- printf "$optfmt" -H "Don't print a header when \`-Y' is given."
- printf "$optfmt" -r "List years in reverse order (oldest first)."
- printf "$optfmt" -v "Verbose. Show years where user made zero commits."
- printf "$optfmt" "-y year" \
- "Specify years to list stats for (default all years)."
- printf "$optfmt" "" "This option can be specified multiple times."
- printf "$optfmt" -Y "Report number of commits made in past 365 days."
- printf "$optfmt" "" "Mutually exclusive to \`-y year'."
- exit $FAILURE
- }
- get_user_years()
- {
- local user="$1" user_newest user_oldest date year
- USER_YEARS=
- NEWESTYEAR=
- OLDESTYEAR=
- # Base years off of actual user commit range
- user_newest=$( p4 changes -u "$user" | awk 'NR==1' )
- user_oldest=$( p4 changes -u "$user" | awk 'END{print}' )
- if [ ! "$user_newest" ]; then
- # No changes by user
- if [ "$VERBOSE" ]; then
- NEWESTYEAR=$THIS_YEAR
- OLDESTYEAR=$THIS_YEAR
- USER_YEARS=$THIS_YEAR
- fi
- elif [ "$user_newest" = "$user_oldest" ]; then
- # User has made exactly one change
- date="${user_newest#* on }"
- NEWESTYEAR="${date%%/*}"
- OLDESTYEAR=$NEWESTYEAR
- USER_YEARS=$NEWESTYEAR
- else
- # User has made multiple changes
- if [ "$VERBOSE" ]; then
- date="${user_newest#* on }"
- NEWESTYEAR="${date%%/*}"
- date="${user_oldest#* on }"
- OLDESTYEAR="${date%%/*}"
- if [ "$REVERSE" ]; then
- USER_YEARS=$( seq $OLDESTYEAR 1 $NEWESTYEAR )
- else
- USER_YEARS=$( seq $NEWESTYEAR -1 $OLDESTYEAR )
- fi
- else
- if [ "$REVERSE" ]; then
- USER_YEARS=$( p4 changes -u "$user" |
- awk '$0=substr($4,1,4)' | sort -un )
- OLDESTYEAR=$( echo $USER_YEARS | head -1 )
- NEWESTYEAR=$( echo $USER_YEARS | tail -1 )
- else
- USER_YEARS=$( p4 changes -u "$user" |
- awk '$0=substr($4,1,4)' | sort -unr )
- NEWESTYEAR=$( echo $USER_YEARS | head -1 )
- OLDESTYEAR=$( echo $USER_YEARS | tail -1 )
- fi
- fi
- fi
- if [ "$VERBOSE" ]; then
- year=$NEWESTYEAR
- while [ $year -lt $THIS_YEAR ]; do
- year=$(( $year + 1 ))
- if [ "$REVERSE" ]; then
- USER_YEARS="$USER_YEARS $year"
- else
- USER_YEARS="$year $USER_YEARS"
- fi
- done
- fi
- [ "$USER_YEARS" ] # return status
- }
- type tac > /dev/null 2>&1 || tac(){ tail -r "$@"; }
- ############################################################ MAIN
- #
- # Command-line options
- #
- while getopts 1Hrvy:Y flag; do
- case "$flag" in
- 1) ONELINE=1 ;;
- H) NOHEADER=1 ;;
- r) REVERSE=1 ;;
- v) VERBOSE=1 ;;
- y) [ "$PAST365" ] && usage "cannot specify both \`-y year' and \`-Y'"
- [ "$OPTARG" = "${OPTARG%[!0-9]*}" -a ${#OPTARG} -eq 4 ] ||
- usage "invalid \`-y' argument -- %s" "$OPTARG"
- YEARS="$YEARS $OPTARG" ;;
- Y) [ "$YEARS" ] && usage "cannot specify both \`-y year' and \`-Y'"
- PAST365=1 ;;
- *) usage
- esac
- done
- shift $(( $OPTIND - 1 ))
- #
- # Validate command-line arguments
- #
- for user in "$@"; do
- case "$user" in
- "") usage "invalid (NULL) user argument" ;;
- *[#@]*) usage "Revision chars (@, #) not allowed in '%s'." "$user" ;;
- *[*]*) usage "Wildcard (*) not allowed in user '%s'." "$user" ;;
- *[^\ !\"#$%\&\'\(\)+,./0-9:\;\<=\>?A-Z\[\\\]^_\`a-z{\|}~-]*)
- usage "Non-printable characters not allowed in '%s'." "$pgm" ;;
- esac
- done
- #
- # Reverse `-y year' arguments if `-r' is given
- #
- [ "$REVERSE" -a "$YEARS" ] && YEARS=$( echo $YEARS | xargs -n1 | tac )
- # NOTREACHED unless all users and all years are valid
- #
- # Report commits by-year for each user argument
- #
- [ "$PAST365" -a ! "$NOHEADER" ] &&
- echo "+++ Per-user statistics for: p4 changes $RANGE365" >&2
- [ $# -gt 0 ] || set -- $( p4 users | awk '$0=$1' | sort )
- for user in "$@"; do
- USER_YEARS="$YEARS"
- [ "$PAST365" -o "$USER_YEARS" ] || get_user_years "$user" || continue
- [ "$ONELINE" ] || print_header=1
- for year in $USER_YEARS; do
- # NOTREACHED if `-Y' given
- ncommits=$( p4 changes -u "$user" @01/01/$year,@12/31/$year |
- awk 'END{print NR}' )
- [ $ncommits -gt 0 -o "$VERBOSE" ] || continue
- if [ "$print_header" ]; then
- print_header=
- printf "+++ Commits by %s:\n" "$user"
- fi
- if [ "$ONELINE" ]; then
- printf "%8u y%4u %s\n" $ncommits $year "$user"
- else
- printf "\t... in the year %u: %u\n" $year $ncommits
- fi
- done
- if [ "$PAST365" ]; then
- # NOTREACHED if `-y year' given
- ncommits=$( p4 changes -u "$user" "$RANGE365" |
- awk 'END{print NR}' )
- [ $ncommits -gt 0 -o "$VERBOSE" ] &&
- printf "%8u %s\n" $ncommits "$user"
- fi
- done
- exit $SUCCESS
- ################################################################################
- # END
- ################################################################################
- #
- # $Copyright: 2015 Devin Teske. All rights reserved. $
- #
- # $Header: //guest/freebsdfrau/p4t/libexec/year#2 $
- #
- ################################################################################
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#2 | 16371 | freebsdfrau | Add `-H' flag to omit header from `-Y' output | 9 years ago | |
#1 | 16365 | freebsdfrau | Import p4t - p4d admin tool | 9 years ago |