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 99# Number of public functions in libcurl 100$apublic=`git grep ^CURL_EXTERN -- include/curl | wc -l`; 101$bpublic=`git grep ^CURL_EXTERN $start -- include/curl | wc -l`; 102$public = $apublic - $bpublic; 103 104# diffstat 105$diffstat=`git diff --stat $start.. | tail -1`; 106if($diffstat =~ /^ *(\d+) files changed, (\d+) insertions\(\+\), (\d+)/) { 107 ($fileschanged, $insertions, $deletions)=($1, $2, $3); 108} 109 110# Changes/bug-fixes currently logged 111open(F, "<RELEASE-NOTES"); 112while(<F>) { 113 if($_ =~ /following changes:/) { 114 $mode=1; 115 } 116 elsif($_ =~ /following bugfixes:/) { 117 $mode=2; 118 } 119 elsif($_ =~ /known bugs:/) { 120 $mode=3; 121 } 122 elsif($_ =~ /like these:/) { 123 $mode=4; 124 } 125 if($_ =~ /^ o /) { 126 if($mode == 1) { 127 $numchanges++; 128 } 129 elsif($mode == 2) { 130 $numbugfixes++; 131 } 132 } 133 if(($mode == 4) && ($_ =~ /^ \((\d+) contributors/)) { 134 $numcontributors = $1; 135 } 136} 137close(F); 138 139######################################################################## 140# Produce the summary 141 142print "== Since $start $taggednice ==\n"; 143my $days = $elapsed / 3600 / 24; 144printf "Elapsed time: %.1f days (total %d)\n", 145 $days, $total / 3600 / 24; 146printf "Commits: %d (total %d)\n", 147 $commits, $acommits; 148printf "Commit authors: %d, %d new (total %d)\n", 149 $committers, $ncommitters, $acommitters; 150printf "Contributors: %d, %d new (total %d)\n", 151 $numcontributors, $contribs, $acontribs; 152printf "New public functions: %d (total %d)\n", 153 $public, $apublic; 154printf "New curl_easy_setopt() options: %d (total %d)\n", 155 $nsetopts, $asetopts; 156printf "New command line options: %d (total %d)\n", 157 $noptions, $aoptions; 158printf "Changes logged: %d\n", $numchanges; 159printf "Bugfixes logged: %d (%.2f per day)\n", 160 $numbugfixes, $numbugfixes / $days; 161printf "Added files: %d (total %d)\n", 162 $creates, $afiles; 163printf "Deleted files: %d (delta: %d)\n", $deletes, 164 $creates - $deletes; 165print "Diffstat:$diffstat" if(!$fileschanged); 166printf "Files changed: %d (%.2f%%)\n", $fileschanged, $fileschanged*100/$afiles; 167printf "Lines inserted: %d\n", $insertions; 168printf "Lines deleted: %d (delta: %d)\n", $deletions, 169 $insertions - $deletions; 170