diff --git a/.gitlab-ci/version.pl b/.gitlab-ci/version.pl index 80eae5e9f..7fa0e1324 100755 --- a/.gitlab-ci/version.pl +++ b/.gitlab-ci/version.pl @@ -60,6 +60,21 @@ my %parKinds = ( def=>'chore=patch,feat=minor,feature=minor,fix=patch,BREAK=major,perf=patch,refactor=patch,test=patch,style=patch,revert=null,docs=patch,build=null,ci=null', help=>'how to react on which commit type; can be partially given. Actions are: "null", "major", "minor", "patch" or state "invalid" for removing this type', }, + changelog=>{ + arity=>1, + def=>'', + help=>'File to add the changelog to; no changelog is written if this parameter is empty.' + }, + changelogout=>{ + arity=>1, + def=>'', + help=>'Use this file name to write the changelog to, but use "changelog" to read the old changelog. If not set for both versions the parameter changelog is used.', + }, + vcsurl=>{ + arity=>1, + def=>'', + help=>'Repository URL for changelog; for example "https://gitlab.example.doc/proj/proj/"', + }, v=>{def=>0,arity=>0,help=>'verbose'}, h=>{def=>0,arity=>0,help=>'help'}, ); @@ -148,6 +163,10 @@ for my $as(split /,/, $par{change}) { } } +if($par{changelog} and not $par{vcsurl}) { + die "Parameter 'changelog' given, but parameter 'vcsurl' is not. Please state the url of your repository for computation of a changelog.\n" +} + #my @have = split /\n/, `$par{vcstags}`; # #my @keep = grep { $_ } map { m#^($par{kind})([0-9].*)# ? [$1,$2] : undef } @have; @@ -481,3 +500,118 @@ while(exists $allVersions{$newVersion}) { print "$newVersion\n"; + + + + + + + +# If we want a changelog +if($par{changelog}) { + #print "Changelog file: '$par{changelog}'\n"; + # TODO at the moment we only extend a changelog; starting with a fresh one is not supportet yet + my $fh = undef; + open($fh, '<', $par{changelog}) or die "Could not read changelog file '$par{changelog}', because: $!"; + my @changelog = <$fh>; + close $fh; + my %seen = (); + my @sects = ([]); + for(@changelog) { + push @sects, [] if m/^## /; + push @{$sects[-1]}, $_; + if(m#/commit/([a-f0-9]+)\s*\)\s*\)\s*$#) { + $seen{$1} = 1; + } + } + my $head = shift @sects; + #print Data::Dumper::Dumper($head); + #print " << $sects[0][0] >>\n"; + if($sects[0][0]=~m/^##\s*\[([^\]\[]+)\]\(/ and $1 eq $newVersion) { + shift @sects; + } + for my $s(@sects) { + my $hh = $s->[0]; + chomp $hh; + my $cnt = @$s; + #print " $hh\n $cnt lines\n\n" + } + #print Data::Dumper::Dumper($versions[0]); + for my $v(@versions) { + #print Data::Dumper::Dumper($v); + my $hash = $v->{hash}; + my $see = 'new'; + $see = 'old' if $seen{$hash}; + #print "$hash -> $see ($v->{subject})\n"; + } + my $changelogout = $par{changelogout} || $par{changelog}; + my $changelogfh = undef; + open($changelogfh, '>', $changelogout) or die "$0: Could not write '$changelogout', because: $!\n"; + my %extend = (); + my %when = ( + 'fix' => 'Bug Fixes', + 'hotfix' => 'Bug Fixes', + 'feat' => 'Features', + 'feature' => 'Features', + ); + SELECTCHANGELOG: for my $v(@versions) { + last SELECTCHANGELOG if $seen{$v->{hash}}; + next unless $v->{subject}=~m#^\s*([a-z]+)\s*(!?)\s*((?:\(.*?\))?)\s*:\s*(.*?)\s*$#i; + my ($kind, $break, $context, $msg) = ($1, $2, $3, $4); + my $where = $when{$kind}; + $where = 'BREAKING CHANGES' if '!' eq $break; + next unless $where; + my $short = substr $v->{hash}, 0, 7; + my $contS = ''; + if($context=~m#\((.*)\)#) { + $contS = "**$1:** "; + } + my $row = qq#* $contS$msg ([$short]($par{vcsurl}commit/$v->{hash}))#; + push @{$extend{$where}}, { + msg=>$msg, + context=>$context, + orig=>$v, + row=>$row, + }; + } + #print Data::Dumper::Dumper(\%extend); + my $preVersion = ''; + if($sects[0][0]=~m/^##\s*\[([^\]\[]+)\]\(/) { + $preVersion = $1; + $preVersion =~ s#^v?#v#; + } + my $today = do { + my @time = localtime; + my $year = $time[5]+1900; + my $month = $time[4]+1; + my $day = $time[3]; + sprintf("%04i-%02i-%02i", $year, $month, $day) + }; + print $changelogfh qq!# Changelog + +All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +## [$newVersion]($par{vcsurl}/compare/$preVersion...$newVersion) ($today) + +!; + for my $variant('BREAKING CHANGES', 'Features', 'Bug Fixes') { + my @all = map {$_->{row}} @{$extend{$variant}}; + next unless @all; + my $msg = join "\n", @all; + print $changelogfh qq/### $variant\n\n$msg\n\n/ + } + for(@sects) { + print $changelogfh $_ for @$_ + } +} + + + + + + + + + + +