Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

effort: handling of $'s and \n's, plus make shellcheck happy #622

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 60 additions & 31 deletions bin/git-effort
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ usage() {
# get dates for the given <commit>
#
dates() {
eval "git log $args_to_git_log --pretty='format: %ad' --date=short \"$1\""
path="$1"
# Escape dollars so they aren't interpreted in eval
path="${1/\$/\\$}"
eval "git log $args_to_git_log --pretty='format: %ad' --date=short \"${path}\""
}

# tput, being quiet about unknown capabilities
Expand Down Expand Up @@ -59,14 +62,14 @@ active_days() {

color_for() {
if [ "$to_tty" = true ]; then
if [ $1 -gt 200 ]; then color="$(tputq setaf 1)$(tputq bold)"
elif [ $1 -gt 150 ]; then color="$(tputq setaf 1)" # red
elif [ $1 -gt 125 ]; then color="$(tputq setaf 2)$(tputq bold)"
elif [ $1 -gt 100 ]; then color="$(tputq setaf 2)" # green
elif [ $1 -gt 75 ]; then color="$(tputq setaf 5)$(tputq bold)"
elif [ $1 -gt 50 ]; then color="$(tputq setaf 5)" # purplish
elif [ $1 -gt 25 ]; then color="$(tputq setaf 3)$(tputq bold)"
elif [ $1 -gt 10 ]; then color="$(tputq setaf 3)" # yellow
if [ "$1" -gt 200 ]; then color="$(tputq setaf 1)$(tputq bold)"
elif [ "$1" -gt 150 ]; then color="$(tputq setaf 1)" # red
elif [ "$1" -gt 125 ]; then color="$(tputq setaf 2)$(tputq bold)"
elif [ "$1" -gt 100 ]; then color="$(tputq setaf 2)" # green
elif [ "$1" -gt 75 ]; then color="$(tputq setaf 5)$(tputq bold)"
elif [ "$1" -gt 50 ]; then color="$(tputq setaf 5)" # purplish
elif [ "$1" -gt 25 ]; then color="$(tputq setaf 3)$(tputq bold)"
elif [ "$1" -gt 10 ]; then color="$(tputq setaf 3)" # yellow
else color="$(tputq sgr0)" # default color
fi
else
Expand All @@ -80,41 +83,63 @@ color_for() {

effort() {
path=$1

# Exit if path == ""
# This is not an error
# shellcheck disable=SC2116
if [ -z "$(head -c 1 <<<"$(echo "$path")")" ]
then
exit 0
fi
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like printf (that produces output to effort) sends a final empty line when we call effort. That's the reason for this check.


local commit_dates
local color reset_color commits len dot f_dot i msg active
reset_color=""
test "$to_tty" = true && reset_color="$(tputq sgr0)"
commit_dates=`dates "$path"`
[ $? -gt 0 ] && exit 255

# Ensure it's not just an empty line
if [ -z "`head -c 1 <<<$(echo $commit_dates)`" ]
if ! commit_dates=$(dates "$path")
then
# 255 should terminate xargs (which runs the effort() function)
exit 255
fi

# If `git log ...` returns nothing, return
# This is not an error
# shellcheck disable=SC2116
if [ -z "$(head -c 1 <<<"$(echo "$commit_dates")")" ]
then
exit 0
fi

commits=`wc -l <<<"$(echo "$commit_dates")"`
color='90'
# shellcheck disable=SC2116
commits=$(wc -l <<<"$(echo "$commit_dates")")
color="$(tputq sgr0)" # default color

# ignore <= --above
test $commits -le $above && exit 0
test "$commits" -le "$above" && exit 0

# commits
color_for $(( $commits - $above ))
# Replace actual newlines with a textual representation.
# We need to print everything in one line, else we get
# a race condition because this function runs in
# parallell. Also, the sorting at the end messes things up.
path="${path/$'\n'/\\n}"

color_for $(( commits - above ))
len=${#path}
dot="."
f_dot="$path"
i=0 ; while test $i -lt $((45-$len)) ; do
i=0 ; while test $i -lt $((45 - len)) ; do
f_dot=$f_dot$dot
i=$(($i+1))
i=$((i + 1))
done

msg=$(printf " ${color}%s %-10d" "$f_dot" $commits)

msg=$(printf " ${color}%s %-10d" "$f_dot" "$commits")

# active days
active=`active_days "$commit_dates"`
color_for $(( $active - $above ))
msg="$msg $(printf "${color} %d${reset_color}\n" $active)"
active=$(active_days "$commit_dates")
color_for $(( active - above ))
msg="$msg $(printf "${color} %d${reset_color}\n" "$active")"
echo "$msg"
}

Expand All @@ -136,7 +161,7 @@ sort_effort() {
clear
echo " "
heading
< $tmp sort -rn -k 2
< "$tmp" sort -rn -k 2
}

declare -a paths=()
Expand Down Expand Up @@ -181,8 +206,8 @@ export args_to_git_log

if test "${#paths}" -eq 0; then
save_ifs=$IFS
IFS=`echo -en "\n\b"`
paths=(`git ls-files`)
IFS=$(echo -en "\n\b")
paths=($(git ls-files))
IFS=$save_ifs
unset save_ifs
fi
Expand All @@ -206,17 +231,21 @@ export log_args
bash_params=
# If bash exits sucessfully with --import-functions,
# then we need to pass it (FreeBSD probably)
bash --import-functions -c ":" 1>/dev/null 2>&1
if [ $? -eq 0 ] ; then
if bash --import-functions -c ":" 1>/dev/null 2>&1
then
bash_params="--import-functions"
fi

heading
# send paths to effort
printf "%s\0" "${paths[@]}" | xargs -0 -n 1 -P 4 -I % bash $bash_params -c "effort \"%\"" | tee $tmp
printf "%s\0" "${paths[@]}" \
| sed 's/\$/\\\$/g' \
| sed "s/\\\n/\\\$\'\\\n\'/g" \
| xargs -0 -n 1 -P 4 -I % bash $bash_params -c "effort \"%\"" \
| tee "$tmp"

# if more than one path, sort and print
test "$(wc -l $tmp | awk '{print $1}')" -gt 1 && sort_effort
test "$(wc -l "$tmp" | awk '{print $1}')" -gt 1 && sort_effort
echo

show_cursor_and_cleanup
51 changes: 45 additions & 6 deletions man/git-effort.1
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "GIT\-EFFORT" "1" "December 2015" "" ""
.TH "GIT\-EFFORT" "1" "January 2017" "" "Git Extras"
.
.SH "NAME"
\fBgit\-effort\fR \- Show effort statistics on file(s)
Expand All @@ -21,6 +21,9 @@ Display includes:
.br
\- Active days: total number of days which contributed modifications to this file\.
.
.P
Because statistics are displayed in a linewise manner, filenames with newlines in them will be displayed with the newline replaced by \fB\en\fR\.
.
.SH "OPTIONS"
\-\-above <value>
.
Expand All @@ -34,13 +37,22 @@ Ignore files with commits <= a value\.
Only count commits that touches the given paths\.
.
.P
\fBgit effort folder_name\fR gives one entry, showing statistics for files in that folder\. \fBgit effort folder_name/*\fR on the other hand, gives an entry for each file in that folder\.
.
.P
Note: \fBgit\-effort\fR does not accept revision ranges, but the underlying \fBgit log\fR does (See the examples)\.
.
.P
<log options>\.\.\.
.
.P
Options for \fBgit log\fR\. Note that you must use \fB\-\-\fR to separate options to \fBgit log\fR from options to \fBgit effort\fR\. This makes it possible to only count commits you are interested in\. Not all options are relevant in the context of \fBgit\-effort\fR, but those that are is listed under the "Commit Limiting" section on the \fBgit\-log\fR manpages\.
Options for \fBgit log\fR\.
.
.br
This makes it possible to limit which commits to count\. Not all options are relevant in the context of \fBgit\-effort\fR, but those that are is listed under the "Commit Limiting" section on the \fBgit\-log\fR manpages\.
.
.P
\fBNote\fR that you probably want to use \fB\-\-\fR to separate options to \fBgit log\fR from options to \fBgit effort\fR\. There are interesting usages of leaving \fB\-\-\fR out, if you understand what happens\. See examples for more on this\.
.
.SH "EXAMPLES"
Note: Output will first appear unsorted, then the screen is cleared and the sorted list is output\. The initial unsorted list is not shown in the examples for brevity\.
Expand All @@ -65,7 +77,17 @@ $ git effort \-\-above 5
git\-summary 8 6
git\-delete\-branch 8 6
git\-repl 7 5

.
.fi
.
.IP "" 0
.
.P
Note the \fB\-\-\fR for separating options to \fBgit log\fR\. This example only counts commits from the past year, and only commits authored by Leila Muhtasib\.
.
.IP "" 4
.
.nf

$ git effort \-\-above 5 bin/* \-\- \-\-after="one year ago" \-\-author="Leila Muhtasib"

Expand Down Expand Up @@ -103,13 +125,12 @@ $ git effort bin man \-\- \-\-after="one year ago"
.P
Only count commits in the specified revision range:
.
.P
$ git effort \-\- master\.\.feature
.
.IP "" 4
.
.nf

$ git effort \-\- master\.\.feature

file commits active days

bin/git\-effort\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. 3 2
Expand All @@ -119,6 +140,24 @@ $ git effort \-\- master\.\.feature
.
.IP "" 0
.
.P
You can "trick" \fBgit effort\fR into thinking that a \fBrevision\fR is a path, to give a summarised view of that revision\. Remember: arguments before the \fB\-\-\fR separator is interpreted as paths\.
.
.IP "" 4
.
.nf

$ git effort master\.\.feature master\.\.hotfix

file commits active days

master\.\.feature\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.4 2
master\.\.hotfix\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.1 1
.
.fi
.
.IP "" 0
.
.SH "AUTHOR"
Written by Leila Muhtasib <\fImuhtasib@gmail\.com\fR>
.
Expand Down
42 changes: 33 additions & 9 deletions man/git-effort.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading