From 872cbf414040a7ce16b0513bc90078a601117bfa Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 26 May 2015 19:52:38 +0200 Subject: [PATCH 1/2] build: make manpage generation reproducible pod2man will insert a date in the footer of the manpage. By default, it takes this value from the mtime of the input file. But this makes it non-deterministic in that another build may produce other results. By setting it to always be the date of the latest release we make it deterministic. --- Makefile | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 201ecd9..8d2026f 100644 --- a/Makefile +++ b/Makefile @@ -3,10 +3,15 @@ all: svtplay-dl .PHONY: test cover doctest pylint svtplay-dl \ release clean_releasedir $(RELEASE_DIR) +# These variables describe the latest release: VERSION = 0.10 -RELEASE = $(VERSION).$(shell date +%Y.%m.%d) -RELEASE_DIR = svtplay-dl-$(RELEASE) -LATEST_RELEASE = 0.10.2015.05.24 +LATEST_RELEASE_DATE = 2015.05.24 +LATEST_RELEASE = $(VERSION).$(LATEST_RELEASE_DATE) + +# If we build a new release, this is what it will be called: +NEW_RELEASE_DATE = $(shell date +%Y.%m.%d) +NEW_RELEASE = $(VERSION).$(NEW_RELEASE_DATE) +RELEASE_DIR = svtplay-dl-$(NEW_RELEASE) PREFIX ?= /usr/local BINDIR = $(PREFIX)/bin @@ -20,8 +25,10 @@ MANFILE = svtplay-dl.1$(MANFILE_EXT) # As pod2man is a perl tool, we have to jump through some hoops # to remove references to perl.. :-) -POD2MAN ?= pod2man --section 1 --utf8 -c "svtplay-dl manual" \ - -r "svtplay-dl $(VERSION)" +POD2MAN ?= pod2man --section 1 --utf8 \ + --center "svtplay-dl manual" \ + --release "svtplay-dl $(VERSION)" \ + --date "$(LATEST_RELEASE_DATE)" PYTHON ?= /usr/bin/env python export PYTHONPATH=lib @@ -61,24 +68,25 @@ doctest: svtplay-dl sh scripts/diff_man_help.sh $(RELEASE_DIR): clean_releasedir - mkdir svtplay-dl-$(RELEASE) - cd svtplay-dl-$(RELEASE) && git clone -b master ../ . && make svtplay-dl + mkdir $(RELEASE_DIR) + cd $(RELEASE_DIR) && git clone -b master ../ . && \ + make svtplay-dl $(MANFILE) clean_releasedir: rm -rf $(RELEASE_DIR) release: $(RELEASE_DIR) release-test set -e; cd $(RELEASE_DIR) && \ - sed -i -r -e 's/^(LATEST_RELEASE = ).*/\1$(RELEASE)/' Makefile;\ - sed -i -r -e 's/^(__version__ = ).*/\1"$(RELEASE)"/' lib/svtplay_dl/__init__.py;\ + sed -i -re 's/^(LATEST_RELEASE_DATE = ).*/\1$(NEW_RELEASE_DATE)/' Makefile;\ + sed -i -re 's/^(__version__ = ).*/\1"$(NEW_RELEASE)"/' lib/svtplay_dl/__init__.py;\ make svtplay-dl; \ git add svtplay-dl Makefile lib/svtplay_dl/__init__.py; \ - git commit -m "Prepare for release $(RELEASE)"; + git commit -m "Prepare for release $(NEW_RELEASE)"; (cd $(RELEASE_DIR) && git format-patch --stdout HEAD^) | git am - git tag -m "New version $(RELEASE)" \ + git tag -m "New version $(NEW_RELEASE)" \ -m "$$(git log --oneline $(LATEST_RELEASE)..HEAD^)" \ - $(RELEASE) + $(NEW_RELEASE) make clean_releasedir From 352fd90e5124a6fbcfbb1763082de1980c4333e5 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Sat, 30 May 2015 01:54:55 +0200 Subject: [PATCH 2/2] build: Truncate timestamps in zip archive Even though zip's -X flag suggests that it removes timestamps, that's not quite true. There's still modification times per file, and that introduces non-determinism that are hard to notice, since the mtimes are unlikely to change without changes to the files. Only when doing a new clone/unpacking a tar ball under some circumstances or similar action that resets/discards the mtimes, we would notice. So, the -X is not enough, and from what I can tell, there's no way of telling zip to not include timestamps (or truncate them). With this change, we stage all files in a temporary .build directory, and set the mtime manually to the beginning of time (as is the case for zip files: 1980-01-01T00:00). These timestamps should not be important to anyone, since they are all presented to the user as a blob. The rationale for this change is that this makes it possible to build svtplay-dl reproducibly. And it also removes the pesky svtplay-dl diffs just from regenerating the executable. --- lib/Makefile | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index 1b4220f..c9c43f4 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -14,14 +14,28 @@ export PACKAGES = svtplay_dl \ svtplay_dl.utils \ svtplay_dl.service \ svtplay_dl.subtitle -export PYFILES = $(addsuffix /*.py,$(subst .,/,$(PACKAGES))) +export PYFILES = $(sort $(addsuffix /*.py,$(subst .,/,$(PACKAGES)))) PYTHON ?= /usr/bin/env python svtplay-dl: $(PYFILES) - zip -X --quiet svtplay-dl $(PYFILES) - zip -X --quiet --junk-paths svtplay-dl svtplay_dl/__main__.py + @# Verify that there's no .build already \ + ! [ -d .build ] || { \ + echo "ERROR: build already in progress? (or remove $(PWD)/.build/)"; \ + exit 1; \ + }; \ + mkdir -p .build + + @# Stage the files in .build for postprocessing + for py in $(PYFILES); do install -D $$py .build/$$py; done + + @# reset timestamps, to avoid non-determinism in zip file + find .build/ -exec touch -m -t 198001010000 {} \; + + (cd .build && zip -X --quiet svtplay-dl $(PYFILES)) + (cd .build && zip -X --quiet --junk-paths svtplay-dl svtplay_dl/__main__.py) + echo '#!$(PYTHON)' > svtplay-dl - cat svtplay-dl.zip >> svtplay-dl - rm svtplay-dl.zip + cat .build/svtplay-dl.zip >> svtplay-dl + rm -rf .build chmod a+x svtplay-dl