| #!/usr/bin/env perl | |
| #*************************************************************************** | |
| # _ _ ____ _ | |
| # Project ___| | | | _ \| | | |
| # / __| | | | |_) | | | |
| # | (__| |_| | _ <| |___ | |
| # \___|\___/|_| \_\_____| | |
| # | |
| # Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. | |
| # | |
| # This software is licensed as described in the file COPYING, which | |
| # you should have received as part of this distribution. The terms | |
| # are also available at https://curl.se/docs/copyright.html. | |
| # | |
| # You may opt to use, copy, modify, merge, publish, distribute and/or sell | |
| # copies of the Software, and permit persons to whom the Software is | |
| # furnished to do so, under the terms of the COPYING file. | |
| # | |
| # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | |
| # KIND, either express or implied. | |
| # | |
| # SPDX-License-Identifier: curl | |
| # | |
| ########################################################################### | |
| # Display changes done in the repository from [tag] until now. | |
| # | |
| # Uses git for repo data. | |
| # Uses docs/THANKS and RELEASE-NOTES for current status. | |
| # | |
| # In the git clone root, invoke 'scripts/delta [release tag]' | |
| $start = $ARGV[0]; | |
| if($start eq "-h") { | |
| print "Usage: summary [tag]\n"; | |
| exit; | |
| } | |
| elsif($start eq "") { | |
| $start = `git tag --sort=taggerdate | grep "^curl-" | tail -1`; | |
| chomp $start; | |
| } | |
| $commits = `git log --oneline $start.. | wc -l`; | |
| $committers = `git shortlog -s $start.. | wc -l`; | |
| $bcommitters = `git shortlog -s $start | wc -l`; | |
| $acommits = `git log --oneline | wc -l`; | |
| $acommitters = `git shortlog -s | wc -l`; | |
| # delta from now compared to before | |
| $ncommitters = $acommitters - $bcommitters; | |
| # number of contributors right now | |
| $acontribs = `./scripts/contrithanks.sh | grep -c '^[^ ]'`; | |
| # number when the tag was set | |
| $bcontribs = `git show $start:docs/THANKS | grep -c '^[^ ]'`; | |
| # delta | |
| $contribs = $acontribs - $bcontribs; | |
| # number of setops: | |
| sub setopts { | |
| my ($f)=@_; | |
| open(H, "$f"); | |
| my $opts; | |
| while(<H>) { | |
| if(/^ CURLOPT(|DEPRECATED)\(/ && ($_ !~ /OBSOLETE/)) { | |
| $opts++; | |
| } | |
| } | |
| close(H); | |
| return $opts; | |
| } | |
| $asetopts = setopts("<include/curl/curl.h"); | |
| $bsetopts = setopts("git show $start:include/curl/curl.h|"); | |
| $nsetopts = $asetopts - $bsetopts; | |
| # Number of command line options: | |
| $aoptions=`grep -c '{"....--' src/tool_listhelp.c`; | |
| $boptions=`git show $start:src/tool_listhelp.c 2>/dev/null | grep -c '{"....--'`; | |
| $noptions=$aoptions - $boptions; | |
| # current local branch | |
| $branch=`git rev-parse --abbrev-ref HEAD 2>/dev/null`; | |
| chomp $branch; | |
| # Number of files in git | |
| $afiles=`git ls-files | wc -l`; | |
| $deletes=`git diff-tree --diff-filter=A -r --summary origin/$branch $start 2>/dev/null | wc -l`; | |
| $creates=`git diff-tree --diff-filter=D -r --summary origin/$branch $start 2>/dev/null| wc -l`; | |
| # Time since that tag | |
| $tagged=`git for-each-ref --format="%(refname:short) | %(taggerdate:unix)" refs/tags/* | grep ^$start | cut "-d|" -f2`; # Unix timestamp | |
| $taggednice=`git for-each-ref --format="%(refname:short) | %(creatordate)" refs/tags/* | grep ^$start | cut '-d|' -f2`; # human readable time | |
| chomp $taggednice; | |
| $now=`date +%s`; | |
| $elapsed=$now - $tagged; # number of seconds since tag | |
| $total=$now - `date -d 19980320 +%s`; | |
| # Number of public functions in libcurl | |
| $apublic=`git grep ^CURL_EXTERN -- include/curl | wc -l`; | |
| $bpublic=`git grep ^CURL_EXTERN $start -- include/curl | wc -l`; | |
| $public = $apublic - $bpublic; | |
| # diffstat | |
| $diffstat=`git diff --stat $start.. | tail -1`; | |
| if($diffstat =~ /^ *(\d+) files changed, (\d+) insertions\(\+\), (\d+)/) { | |
| ($fileschanged, $insertions, $deletions)=($1, $2, $3); | |
| } | |
| # Changes/bug-fixes currently logged | |
| open(F, "<RELEASE-NOTES"); | |
| while(<F>) { | |
| if($_ =~ /following changes:/) { | |
| $mode=1; | |
| } | |
| elsif($_ =~ /following bugfixes:/) { | |
| $mode=2; | |
| } | |
| elsif($_ =~ /known bugs:/) { | |
| $mode=3; | |
| } | |
| elsif($_ =~ /like these:/) { | |
| $mode=4; | |
| } | |
| if($_ =~ /^ o /) { | |
| if($mode == 1) { | |
| $numchanges++; | |
| } | |
| elsif($mode == 2) { | |
| $numbugfixes++; | |
| } | |
| } | |
| if(($mode == 4) && ($_ =~ /^ \((\d+) contributors/)) { | |
| $numcontributors = $1; | |
| } | |
| } | |
| close(F); | |
| ######################################################################## | |
| # Produce the summary | |
| print "== Since $start $taggednice ==\n"; | |
| my $days = $elapsed / 3600 / 24; | |
| printf "Elapsed time: %.1f days (total %d)\n", | |
| $days, $total / 3600 / 24; | |
| printf "Commits: %d (total %d)\n", | |
| $commits, $acommits; | |
| printf "Commit authors: %d, %d new (total %d)\n", | |
| $committers, $ncommitters, $acommitters; | |
| printf "Contributors: %d, %d new (total %d)\n", | |
| $numcontributors, $contribs, $acontribs; | |
| printf "New public functions: %d (total %d)\n", | |
| $public, $apublic; | |
| printf "New curl_easy_setopt() options: %d (total %d)\n", | |
| $nsetopts, $asetopts; | |
| printf "New command line options: %d (total %d)\n", | |
| $noptions, $aoptions; | |
| printf "Changes logged: %d\n", $numchanges; | |
| printf "Bugfixes logged: %d (%.2f per day)\n", | |
| $numbugfixes, $numbugfixes / $days; | |
| printf "Added files: %d (total %d)\n", | |
| $creates, $afiles; | |
| printf "Deleted files: %d (delta: %d)\n", $deletes, | |
| $creates - $deletes; | |
| print "Diffstat:$diffstat" if(!$fileschanged); | |
| printf "Files changed: %d (%.2f%%)\n", $fileschanged, $fileschanged*100/$afiles; | |
| printf "Lines inserted: %d\n", $insertions; | |
| printf "Lines deleted: %d (delta: %d)\n", $deletions, | |
| $insertions - $deletions; |