diff --git a/Makefile b/Makefile index f05a5699d086643a936e46d083611f1707597412..a3e78c3e500e832843b7f763caf744920c3bdf2e 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,8 @@ TOP ?= model.pdf TOP_NAME = $(patsubst %.pdf,%,$(TOP)) EXT = pdf log aux out bbl blg toc snm nav fdb_latexmk fls +STYS = $(wildcard texinputs/*.sty) + FIGS = $(wildcard figs/*.fig) FIGS_PDF = $(patsubst %.fig,%.pdftex,$(FIGS)) FIGS_PDF_T = $(patsubst %.fig,%.pdftex_t,$(FIGS)) @@ -19,6 +21,7 @@ NEEDED = $(FIGS_PDF) $(FIGS_PDF_T) $(SVGS_PDF) $(ODGS_PDF) # Only for package documentation. NEEDED_DOC = $(TOP_NAME)-slide2.pdf +RELEASE_SCRIPT = debian/make-release PREVIEW_OPTS = \RequirePackage[active,delayed,tightpage,graphics,pdftex] {preview} PREVIEW_OPTS += \PreviewMacro[{*[][]{}}]{\incode} @@ -27,7 +30,7 @@ export TEXINPUTS := ./texinputs/:$(TEXINPUTS) #.SECONDARY: $(FIGS_PDF) -.PHONY: all clean dep preview +.PHONY: all clean dep preview release all: $(TOP) @@ -35,8 +38,8 @@ $(TOP) : dep dep: $(NEEDED) $(NEEDED_DOC) -%.pdf:%.tex texinputs/beamerthemetptnew.sty - @echo "Latex search path $(TEXINPUTS)" +%.pdf:%.tex $(STYS) + @echo "LaTeX search path $(TEXINPUTS)" @latexmk -pdf $< preview: dep @@ -66,3 +69,10 @@ clean: # Only for package documentation. $(TOP_NAME)-slide2.tex : $(TOP_NAME).tex @perl -pE 'if (m{^%+ Stop ici}i) { say "\\end{document}"; last; }' $< > $@ + +# Only for package installation and packaging. +# Usage: make release V=-v<x>.<y>.<z>. If V is not given, +# it will be calculated from the latest version-like tag +# (and incremented unless working copy is clean and at the tag). +release: + perl -i.orig $(RELEASE_SCRIPT) $(V) $(STYS) $(TOP_NAME).tex diff --git a/debian/make-release b/debian/make-release new file mode 100755 index 0000000000000000000000000000000000000000..415c59731c4fa503ec30a3175f3abc60d56b4905 --- /dev/null +++ b/debian/make-release @@ -0,0 +1,161 @@ +#! /usr/bin/env perl + +# +# Filter calls to some LaTeX macros: +# \date{...} -> \date{date} +# \ProvidesPackage{...}[...] -> \ProvidesPackage{...}[date version] +# +# If you want to filter and replace files instead of stdin, +# invoke with perl -i. +# +# Version and date are either specified on the command line (-v, -d) +# or determined from Git tags and/or today's date. If the Git +# working copy in the current directory is clean and exactly at a +# version tag, use that version and commit date. Otherwise use +# a version number incremented from the last version tag, +# and today's date. +# + +use 5.012; +use strict; +use warnings; +use FindBin; +use Date::Simple qw(date today); +use Getopt::Long qw(:config bundling); + +# Function prototypes and global variables. +sub parse_options(); +sub get_version_from_git(); +sub get_date_from_git(); +sub next_version($); +our ($version, $date); + +# +# Program logic. +# + +# Get options and version from Git tags. +# Increase version from Git tag unless working copy is exactly at this tag, +# in which case also get commit date of this tag. +parse_options(); +my ($v, $c) = get_version_from_git() unless $version; +$v = next_version($v) if ($v && ! $c); +$version //= $v; +$version =~ s{^v?}{v}; # Make sure version starts with "v". +$date //= $c ? get_date_from_git() : today(); +say STDERR "Updating to version $version, date $date."; + +# Standard LaTeX date isn't ISO but uses slashes. +my $date_l = "$date"; +$date_l =~ y{-}{/}; + +# Filter. +while (<>) { + s{(\\date\s*)\{([^{}]*)\}}{${1}\{$date\}}g; + s{(\\ProvidesPackage\s*\{([^{}]*)\}\s*)\[([^\[\]]*)\] + }{$1\[$date_l $version\]}gx; + print; +} + +# If working copy was previously in a clean state, check whether it still is. +# In which case everything is already up to date. +if ($c) { + my ($v, $d, $c) = get_version_from_git(); + if ($c) { + say STDERR "Everything already up to date."; + exit 0; + } else { + sat STDERR "Bad version tag. Re-run script."; + exit 3; + } +} + +# Say what to do now. +say STDERR <<EOT; +Now check that the version is correct, commit, and apply version tag: + +\tgit status +\tgit commit -a +\tgit tag $version +\tgit push origin $version + +EOT + + +exit 0; + +# +# Functions. +# + +sub parse_options() { + my $usage; + my $date_t; + GetOptions('help|h|?' => sub { $usage = 1; die('!FINISH'); }, + 'version|v=s' => \$version, + 'date|d=s' => \$date_t) + or $usage = 1; + if ($version && $version !~ m{^v?\d([\d\w.-])*$}) { + say STDERR "Illegal version: '$version'"; + $usage = 2; + } + if ($date_t) { + $date = date($date_t); + if (! $date) { + say STDERR "Illegal date: '$date_t'"; + $usage = 2; + } + } + if ($usage) { + say STDERR "Usage: $FindBin::Script [-v <version>] [-d <YYYY-MM-DD>]"; + exit $usage; + } +} + + +# Get version from Git tags. +# Returns ($version, $clean_at_tag). +sub get_version_from_git() { + # + # Last tag and working copy state. Use "git describe" to get + # latest tag matching "v<number>". If the working copy is not + # at this tag, it appends -<number of commits>-g<last commit hash>; + # it it is dirty, it appends "-*". Remove these parts, but note + # that the working copy is not at the tag. + # + my $clean_at_tag; + my $tag = `git describe --tags --always --dirty='-*' --match 'v[0-9]*'`; + chomp $tag; + if ($tag =~ m{-+(\*|\d+-g[0-9a-f]+)$}) { + $tag = $`; + } else { + $clean_at_tag = 1; + } + return ($tag, $clean_at_tag); +} + +# Get date of Git last commit (as Date::Simple object). +sub get_date_from_git() { + my $commit_date = + `git --no-pager log -1 --date=short --pretty=format:\%cd HEAD`; + my $d = date($commit_date) + or die("Git returned invalid date '$commit_date'"); + return $d; +} + +# +# Increase version number. +# +sub next_version($) { + my ($v) = @_; + my @items = split(m{\b}, $v); + + # Increment the last part of the version. + $items[-1]++; + + # Make sure the version has at least 2 parts, and starts with "v". + push @items, ".", "0" if ($#items < 2); + $v = join "", @items; + $v =~ s{^v?}{v}; + return $v; +}