1#!/usr/bin/env perl 2#*************************************************************************** 3# _ _ ____ _ 4# Project ___| | | | _ \| | 5# / __| | | | |_) | | 6# | (__| |_| | _ <| |___ 7# \___|\___/|_| \_\_____| 8# 9# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 10# 11# This software is licensed as described in the file COPYING, which 12# you should have received as part of this distribution. The terms 13# are also available at https://curl.se/docs/copyright.html. 14# 15# You may opt to use, copy, modify, merge, publish, distribute and/or sell 16# copies of the Software, and permit persons to whom the Software is 17# furnished to do so, under the terms of the COPYING file. 18# 19# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 20# KIND, either express or implied. 21# 22# SPDX-License-Identifier: curl 23# 24########################################################################### 25 26# Display changes done in the repository from [tag] until now. 27# 28# Uses git for repo data. 29# Uses docs/THANKS and RELEASE-NOTES for current status. 30# 31# In the git clone root, invoke 'scripts/delta [release tag]' 32 33$start = $ARGV[0]; 34 35if($start eq "-h") { 36 print "Usage: summary [tag]\n"; 37 exit; 38} 39elsif($start eq "") { 40 $start = `git tag --sort=taggerdate | grep "^curl-" | tail -1`; 41 chomp $start; 42} 43 44$commits = `git log --oneline $start.. | wc -l`; 45$committers = `git shortlog -s $start.. | wc -l`; 46$bcommitters = `git shortlog -s $start | wc -l`; 47 48$acommits = `git log --oneline | wc -l`; 49$acommitters = `git shortlog -s | wc -l`; 50 51# delta from now compared to before 52$ncommitters = $acommitters - $bcommitters; 53 54# number of contributors right now 55$acontribs = `./scripts/contrithanks.sh | grep -c '^[^ ]'`; 56# number when the tag was set 57$bcontribs = `git show $start:docs/THANKS | grep -c '^[^ ]'`; 58# delta 59$contribs = $acontribs - $bcontribs; 60 61# number of setops: 62sub setopts { 63 my ($f)=@_; 64 open(H, "$f"); 65 my $opts; 66 while(<H>) { 67 if(/^ CURLOPT(|DEPRECATED)\(/ && ($_ !~ /OBSOLETE/)) { 68 $opts++; 69 } 70 } 71 close(H); 72 return $opts; 73} 74$asetopts = setopts("<include/curl/curl.h"); 75$bsetopts = setopts("git show $start:include/curl/curl.h|"); 76$nsetopts = $asetopts - $bsetopts; 77 78# Number of command line options: 79$aoptions=`grep -c '{"....--' src/tool_listhelp.c`; 80$boptions=`git show $start:src/tool_listhelp.c 2>/dev/null | grep -c '{"....--'`; 81$noptions=$aoptions - $boptions; 82 83# current local branch 84$branch=`git rev-parse --abbrev-ref HEAD 2>/dev/null`; 85chomp $branch; 86# Number of files in git 87$afiles=`git ls-files | wc -l`; 88$deletes=`git diff-tree --diff-filter=A -r --summary origin/$branch $start 2>/dev/null | wc -l`; 89$creates=`git diff-tree --diff-filter=D -r --summary origin/$branch $start 2>/dev/null| wc -l`; 90 91# Time since that tag 92$tagged=`git for-each-ref --format="%(refname:short) | %(taggerdate:unix)" refs/tags/* | grep ^$start | cut "-d|" -f2`; # Unix timestamp 93$taggednice=`git for-each-ref --format="%(refname:short) | %(creatordate)" refs/tags/* | grep ^$start | cut '-d|' -f2`; # human readable time 94chomp $taggednice; 95$now=`date +%s`; 96$elapsed=$now - $tagged; # number of seconds since tag 97$total=$now - `date -d 19980320 +%s`; 98$totalhttpget=$now - `date -d 19961111 +%s`; 99 100# Number of public functions in libcurl 101$apublic=`git grep ^CURL_EXTERN -- include/curl | wc -l`; 102$bpublic=`git grep ^CURL_EXTERN $start -- include/curl | wc -l`; 103$public = $apublic - $bpublic; 104 105# diffstat 106$diffstat=`git diff --stat $start.. | tail -1`; 107if($diffstat =~ /^ *(\d+) files changed, (\d+) insertions\(\+\), (\d+)/) { 108 ($fileschanged, $insertions, $deletions)=($1, $2, $3); 109} 110 111# Changes/bug-fixes currently logged 112open(F, "<RELEASE-NOTES"); 113while(<F>) { 114 if($_ =~ /following changes:/) { 115 $mode=1; 116 } 117 elsif($_ =~ /following bugfixes:/) { 118 $mode=2; 119 } 120 elsif($_ =~ /known bugs:/) { 121 $mode=3; 122 } 123 elsif($_ =~ /like these:/) { 124 $mode=4; 125 } 126 if($_ =~ /^ o /) { 127 if($mode == 1) { 128 $numchanges++; 129 } 130 elsif($mode == 2) { 131 $numbugfixes++; 132 } 133 } 134 if(($mode == 4) && ($_ =~ /^ \((\d+) contributors/)) { 135 $numcontributors = $1; 136 } 137} 138close(F); 139 140######################################################################## 141# Produce the summary 142 143print "== Since $start $taggednice ==\n"; 144my $days = $elapsed / 3600 / 24; 145printf "Elapsed time: %.1f days (total %d / %d)\n", 146 $days, $total / 3600 / 24, $totalhttpget / 3600 / 24; 147printf "Commits: %d (total %d)\n", 148 $commits, $acommits; 149printf "Commit authors: %d, %d new (total %d)\n", 150 $committers, $ncommitters, $acommitters; 151printf "Contributors: %d, %d new (total %d)\n", 152 $numcontributors, $contribs, $acontribs; 153printf "New public functions: %d (total %d)\n", 154 $public, $apublic; 155printf "New curl_easy_setopt() options: %d (total %d)\n", 156 $nsetopts, $asetopts; 157printf "New command line options: %d (total %d)\n", 158 $noptions, $aoptions; 159printf "Changes logged: %d\n", $numchanges; 160printf "Bugfixes logged: %d (%.2f per day)\n", 161 $numbugfixes, $numbugfixes / $days; 162printf "Added files: %d (total %d)\n", 163 $creates, $afiles; 164printf "Deleted files: %d (delta: %d)\n", $deletes, 165 $creates - $deletes; 166print "Diffstat:$diffstat" if(!$fileschanged); 167printf "Files changed: %d (%.2f%%)\n", $fileschanged, $fileschanged*100/$afiles; 168printf "Lines inserted: %d\n", $insertions; 169printf "Lines deleted: %d (delta: %d)\n", $deletions, 170 $insertions - $deletions; 171