@@ -28,6 +28,15 @@ COLOR_DARKEST_RED=$(tput setaf 52)
2828COLOR_GRAY=$( tput setaf 240)
2929COLOR_RESET=$( tput sgr0)
3030
31+ # Detect GNU date command (may be 'gdate' on FreeBSD/macOS with coreutils)
32+ if date --version > /dev/null 2>&1 ; then
33+ _DATE_CMD=" date"
34+ elif gdate --version > /dev/null 2>&1 ; then
35+ _DATE_CMD=" gdate"
36+ else
37+ _DATE_CMD=" date"
38+ fi
39+
3140# Beginning git log date. Respects all git datetime formats
3241# If $_GIT_SINCE is never set, look at the repository to find the first date.
3342# NOTE: previously this put the date at the fixed GIT epoch (May 2005)
@@ -45,7 +54,7 @@ _until=${_GIT_UNTIL:-}
4554if [[ -n " ${_until} " ]]; then
4655 _until=" --until=$_until "
4756else
48- _until=" --until=$( LC_TIME=C date ' +%a, %d %b %Y %H:%M:%S %Z' ) "
57+ _until=" --until=$( LC_TIME=C $_DATE_CMD ' +%a, %d %b %Y %H:%M:%S %Z' ) "
4958fi
5059
5160# Set files or directories to be excluded in stats
@@ -128,13 +137,13 @@ function commitsCalendarByAuthor() {
128137 # Gather commit counts
129138 git -c log.showSignature=false log --use-mailmap $_merges \
130139 --date=iso --author=" $author " " $_since " " $_until " $_log_options \
131- --pretty=' %ad' $_pathspec | awk '
140+ --pretty=' %ad' $_pathspec | awk -v date_cmd= " $_DATE_CMD " '
132141 {
133142 split($0, a, " ");
134143 # a[1] = YYYY-MM-DD
135144 split(a[1], date_fields, "-");
136145 mon = date_fields[2] + 0;
137- cmd = "date -d \"" a[1] "\" +%u";
146+ cmd = date_cmd " -d \"" a[1] "\" +%u";
138147 cmd | getline weekday;
139148 close(cmd);
140149 # weekday: 1=Mon, ..., 7=Sun
@@ -204,14 +213,14 @@ function commitsHeatmap() {
204213
205214 local i
206215 for i in $( seq $(( _commit_days- 1 )) -1 0) ; do
207- local day=$( date -d " -$i days" +" %Y-%m-%d" )
208- if [[ $( date -d " $day " +%u) -gt 5 ]]; then
216+ local day=$( $_DATE_CMD -d " -$i days" +" %Y-%m-%d" )
217+ if [[ $( $_DATE_CMD -d " $day " +%u) -gt 5 ]]; then
209218 echo -en " ${COLOR_GRAY} "
210219 else
211220 echo -en " ${COLOR_RESET} "
212221 fi
213222
214- local dayName=$( date -d " $day " +%a)
223+ local dayName=$( $_DATE_CMD -d " $day " +%a)
215224 printf " %s | %s |" " $dayName " " $day "
216225
217226 declare -a commits_per_hour
@@ -264,7 +273,7 @@ function commitsHeatmap() {
264273# ###############################################################################
265274function checkUtils() {
266275 readonly MSG=" not found. Please make sure this is installed and in PATH."
267- readonly UTILS=" awk basename cat column date echo git grep head printf seq \
276+ readonly UTILS=" awk basename cat column echo git grep head printf seq \
268277 sort tput tr uniq"
269278
270279 for u in $UTILS
@@ -274,16 +283,13 @@ function checkUtils() {
274283
275284 # NOTE: The --version flag is only available in GNU date which is required
276285 # for how the current date/time strings are used in this shell script.
277- # To fully support the legacy BSD date found in a default install within
278- # macOS and older distributions of Linux and Unix, a handful of helper
279- # functions can probably be created to handle every case of incompatibility
280- # between the two. Until that's implemented, it is probably best to warn
281- # the user that this will not work rather than having it silently bomb out
282- # during runtime.
283- if ! date --version > /dev/null 2>&1 ; then
286+ # On FreeBSD and macOS the system date is BSD date; GNU date may be
287+ # installed as 'gdate' via coreutils. _DATE_CMD is auto-detected above.
288+ if ! " $_DATE_CMD " --version > /dev/null 2>&1 ; then
284289 echo " ERROR: GNU date is required."
285- echo " If you're on macOS, please install it using 'brew install coreutils'."
286- echo " Ensure that your PATH is configured to use GNU date as well."
290+ echo " On macOS, install it with: brew install coreutils"
291+ echo " On FreeBSD, install it with: pkg install coreutils (provides gdate)"
292+ echo " Ensure that GNU date (or gdate) is in your PATH."
287293 echo " See the README.md for further details."
288294 exit 1
289295 fi
@@ -680,7 +686,7 @@ function changelogs() {
680686 local _author=" "
681687 local commits=" "
682688 local author=" ${1:- } "
683- local next=$( date +%F)
689+ local next=$( $_DATE_CMD +%F)
684690
685691 if [[ -z " ${author} " ]]; then
686692 optionPicked " Git changelogs:"
@@ -979,7 +985,7 @@ function newContributors() {
979985 local firstCommit=$( git -c log.showSignature=false log --author=" $c " \
980986 --reverse --use-mailmap $_merges " $_since " " $_until " \
981987 --format=' %at' $_log_options $_pathspec | filter_ignored_authors | head -n 1)
982- if [[ $firstCommit -ge $( date -d " $newDate " +%s) ]]; then
988+ if [[ $firstCommit -ge $( $_DATE_CMD -d " $newDate " +%s) ]]; then
983989 echo " $c "
984990 fi
985991 done
@@ -1044,7 +1050,7 @@ function parse_year() {
10441050 # Handle the raw UNIX timestamp format i.e. 1697375696 +0000
10451051 if [[ " $date_str " =~ ^[0-9]+ (\ [+-][0-9]{4})? $ ]]; then
10461052 timestamp=$( echo " $date_str " | awk ' {print $1}' )
1047- year=$( date -d " @$timestamp " ' +%Y' 2> /dev/null)
1053+ year=$( $_DATE_CMD -d " @$timestamp " ' +%Y' 2> /dev/null)
10481054 else
10491055 # Default case can get funky. We need to create a clever regex to
10501056 # handle the default case which is like Mon Oct 15 12:34:56 2023 +0000
@@ -1065,7 +1071,7 @@ function parse_year() {
10651071 date_str=$( echo " $date_str " | awk -F' /' ' {print $2"/"$1"/"$3}' )
10661072 fi
10671073 # Extract the final date
1068- year=$( date -d " $date_str " ' +%Y' 2> /dev/null)
1074+ year=$( $_DATE_CMD -d " $date_str " ' +%Y' 2> /dev/null)
10691075 fi
10701076
10711077 echo " $year "
@@ -1361,7 +1367,7 @@ if [[ "$#" -eq 1 ]]; then
13611367 # what people may try. This script doesn't provide any additional
13621368 # output for a bad date since `date`'s STDERR already contains
13631369 # useful information.
1364- if ! date -d " ${newDate} " +%s > /dev/null 2>&1 ; then
1370+ if ! $_DATE_CMD -d " ${newDate} " +%s > /dev/null 2>&1 ; then
13651371 newDate=" "
13661372 fi
13671373 done
@@ -1458,7 +1464,7 @@ if [[ "$#" -eq 0 ]]; then
14581464 11) newDate=" "
14591465 while [[ -z " ${newDate} " ]]; do
14601466 read -r -p " Since what date? (e.g. '2023-04-13', '13 April 2023', 'last Thursday') " newDate
1461- if ! date -d " ${newDate} " +%s > /dev/null 2>&1 ; then
1467+ if ! $_DATE_CMD -d " ${newDate} " +%s > /dev/null 2>&1 ; then
14621468 newDate=" "
14631469 fi
14641470 done
0 commit comments