Source: dispcalgui Version: 3.1.5.0-1 Severity: wishlist Tags: patch User: reproducible-bui...@lists.alioth.debian.org Usertags: timestamps X-Debbugs-Cc: reproducible-bui...@lists.alioth.debian.org
Hi, Whilst working on the Reproducible Builds effort [0], I noticed that dispcalgui could not be built reproducibly. Patch attached. [0] https://reproducible-builds.org/ Regards, -- ,''`. : :' : Chris Lamb `. `'` la...@debian.org / chris-lamb.co.uk `-
--- a/.pc/01_reproducible-build.diff/setup.py 2016-08-24 23:08:44.542458026 +0100 --- b/.pc/01_reproducible-build.diff/setup.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,1162 +0,0 @@ -#!/usr/bin/env python2 -# -*- coding: utf-8 -*- - -from __future__ import with_statement -from ConfigParser import RawConfigParser -from distutils.sysconfig import get_python_lib -from distutils.util import change_root, get_platform -from hashlib import md5, sha1 -from subprocess import call, Popen -from time import gmtime, strftime, timezone -import codecs -import glob -import math -import os -import re -import shutil -import subprocess as sp -import sys -import time -if sys.platform == "win32": - import msilib - -sys.path.insert(0, "DisplayCAL") - -from util_os import fs_enc, which -from util_str import strtr - -pypath = os.path.abspath(__file__) -pydir = os.path.dirname(pypath) - -def create_appdmg(zeroinstall=False): - if zeroinstall: - dmgname = name + "-0install" - srcdir = "0install" - else: - dmgname = name + "-" + version - srcdir = "py2app.%s-py%s" % (get_platform(), sys.version[:3]) - retcode = call(["hdiutil", "create", os.path.join(pydir, "dist", - dmgname + ".dmg"), - "-volname", dmgname, "-srcfolder", - os.path.join(pydir, "dist", srcdir, dmgname)]) - if retcode != 0: - sys.exit(retcode) - - -def replace_placeholders(tmpl_path, out_path, lastmod_time=0, iterable=None): - global longdesc - with codecs.open(tmpl_path, "r", "UTF-8") as tmpl: - tmpl_data = tmpl.read() - if os.path.basename(tmpl_path).startswith("debian"): - longdesc_backup = longdesc - longdesc = "\n".join([" " + (line if line.strip() else ".") - for line in longdesc.splitlines()]) - mapping = { - "DATE": - strftime("%a %b %d %Y", # e.g. Tue Jul 06 2010 - gmtime(lastmod_time or - os.stat(tmpl_path).st_mtime)), - "DATETIME": strftime("%a %b %d %H:%M:%S UTC %Y", # e.g. Wed Jul 07 15:25:00 UTC 2010 - gmtime(lastmod_time or - os.stat(tmpl_path).st_mtime)), - "DEBPACKAGE": name.lower(), - "DEBDATETIME": strftime("%a, %d %b %Y %H:%M:%S ", # e.g. Wed, 07 Jul 2010 15:25:00 +0100 - gmtime(lastmod_time or - os.stat(tmpl_path).st_mtime)) + - ("+" if timezone < 0 else "-") + - strftime("%H%M", gmtime(abs(timezone))), - "DOMAIN": domain.lower(), - "ISODATE": - strftime("%Y-%m-%d", - gmtime(lastmod_time or - os.stat(tmpl_path).st_mtime)), - "ISODATETIME": - strftime("%Y-%m-%dT%H:%M:%S", - gmtime(lastmod_time or - os.stat(tmpl_path).st_mtime)) + - ("+" if timezone < 0 else "-") + - strftime("%H:%M", gmtime(abs(timezone))), - "ISOTIME": - strftime("%H:%M", - gmtime(lastmod_time or - os.stat(tmpl_path).st_mtime)), - "TIMESTAMP": str(int(lastmod_time)), - "SUMMARY": description, - "DESC": longdesc, - "APPDATADESC": "<p>\n\t\t\t" + longdesc.replace("\n", "\n\t\t\t").replace(".\n", ".\n\t\t</p>\n\t\t<p>\n") + "\n\t\t</p>", - "APPNAME": name, - "APPNAME_HTML": name_html, - "APPNAME_LOWER": name.lower(), - "AUTHOR": author, - "AUTHOR_EMAIL": author_email, - "MAINTAINER": author, - "MAINTAINER_EMAIL": author_email, - "MAINTAINER_EMAIL_SHA1": sha1(author_email).hexdigest(), - "PACKAGE": name, - "PY_MAXVERSION": ".".join(str(n) for n in py_maxversion), - "PY_MINVERSION": ".".join(str(n) for n in py_minversion), - "VERSION": version, - "VERSION_SHORT": re.sub("(?:\.0){1,2}$", "", version), - "URL": "http://%s/" % domain.lower(), - "WX_MINVERSION": ".".join(str(n) for n in wx_minversion), - "YEAR": strftime("%Y", gmtime())} - mapping.update(iterable or {}) - for key, val in mapping.iteritems(): - tmpl_data = tmpl_data.replace("${%s}" % key, val) - if os.path.basename(tmpl_path).startswith("debian"): - longdesc = longdesc_backup - if os.path.isfile(out_path): - with codecs.open(out_path, "r", "UTF-8") as out: - data = out.read() - if data == tmpl_data: - return - elif not os.path.isdir(os.path.dirname(out_path)): - os.makedirs(os.path.dirname(out_path)) - with codecs.open(out_path, "w", "UTF-8") as out: - out.write(tmpl_data) - - -def svnversion_bump(svnversion): - print "Bumping version number %s ->" % \ - ".".join(svnversion), - svnversion = svnversion_parse( - str(int("".join(svnversion)) + 1)) - print ".".join(svnversion) - return svnversion - - -def svnversion_parse(svnversion): - svnversion = [n for n in svnversion] - if len(svnversion) > 4: - svnversion = ["".join(svnversion[:len(svnversion) - 3])] + \ - svnversion[len(svnversion) - 3:] - # e.g. ["1", "1", "2", "5", "0"] -> ["11", "2", "5", "0"] - elif len(svnversion) < 4: - svnversion.insert(0, "0") - # e.g. ["2", "8", "3"] -> ["0", "2", "8", "3"] - return svnversion - - -def setup(): - - if sys.platform == "darwin": - bdist_cmd = "py2app" - elif sys.platform == "win32": - bdist_cmd = "py2exe" - else: - bdist_cmd = "bdist_bbfreeze" - if "bdist_standalone" in sys.argv[1:]: - i = sys.argv.index("bdist_standalone") - sys.argv = sys.argv[:i] + sys.argv[i + 1:] - if not bdist_cmd in sys.argv[1:i]: - sys.argv.insert(i, bdist_cmd) - elif "bdist_bbfreeze" in sys.argv[1:]: - bdist_cmd = "bdist_bbfreeze" - elif "bdist_pyi" in sys.argv[1:]: - bdist_cmd = "pyi" - elif "py2app" in sys.argv[1:]: - bdist_cmd = "py2app" - elif "py2exe" in sys.argv[1:]: - bdist_cmd = "py2exe" - - appdata = "appdata" in sys.argv[1:] - arch = None - bdist_appdmg = "bdist_appdmg" in sys.argv[1:] - bdist_deb = "bdist_deb" in sys.argv[1:] - bdist_lipa = "bdist_lipa" in sys.argv[1:] - bdist_pyi = "bdist_pyi" in sys.argv[1:] - buildservice = "buildservice" in sys.argv[1:] - setup_cfg = None - dry_run = "-n" in sys.argv[1:] or "--dry-run" in sys.argv[1:] - help = False - inno = "inno" in sys.argv[1:] - onefile = "-F" in sys.argv[1:] or "--onefile" in sys.argv[1:] - purge = "purge" in sys.argv[1:] - purge_dist = "purge_dist" in sys.argv[1:] - use_setuptools = "--use-setuptools" in sys.argv[1:] - zeroinstall = "0install" in sys.argv[1:] - stability = "testing" - - argv = list(sys.argv[1:]) - for i, arg in enumerate(reversed(argv)): - n = len(sys.argv) - i - 1 - arg = arg.split("=") - if len(arg) == 2: - if arg[0] == "--force-arch": - arch = arg[1] - elif arg[0] in ("--cfg", "--stability"): - if arg[0] == "--cfg": - setup_cfg = arg[1] - else: - stability = arg[1] - sys.argv = sys.argv[:n] + sys.argv[n + 1:] - elif arg[0] == "-h" or arg[0].startswith("--help"): - help = True - - lastmod_time = 0 - - non_build_args = filter(lambda arg: arg in sys.argv[1:], - ["bdist_appdmg", "clean", "purge", "purge_dist", - "uninstall", "-h", "--help", "--help-commands", - "--all", "--name", "--fullname", "--author", - "--author-email", "--maintainer", - "--maintainer-email", "--contact", - "--contact-email", "--url", "--license", - "--licence", "--description", - "--long-description", "--platforms", - "--classifiers", "--keywords", "--provides", - "--requires", "--obsoletes", "--quiet", "-q", - "register", "--list-classifiers", "upload", - "--use-distutils", "--use-setuptools", - "--verbose", "-v", "finalize_msi"]) - - if os.path.isdir(os.path.join(pydir, ".svn")) and (which("svn") or - which("svn.exe")) and ( - not sys.argv[1:] or (len(non_build_args) < len(sys.argv[1:]) and - not help)): - print "Trying to get SVN version information..." - svnversion = None - try: - p = Popen(["svnversion"], stdout=sp.PIPE, cwd=pydir) - except Exception, exception: - print "...failed:", exception - else: - svnversion = p.communicate()[0] - svnversion = strtr(svnversion.strip().split(":")[-1], "MPS") - svnbasefilename = os.path.join(pydir, "VERSION_BASE") - if os.path.isfile(svnbasefilename): - with open(svnbasefilename) as svnbasefile: - svnbase = int("".join(svnbasefile.read().strip().split(".")), - 10) - svnversion = int(svnversion) - svnversion += svnbase - svnversion = svnversion_parse(str(svnversion)) - svnbase = svnversion - - print "Trying to get SVN information..." - mod = False - lastmod = "" - entries = [] - args = ["svn", "status", "--xml"] - while not entries: - try: - p = Popen(args, stdout=sp.PIPE, cwd=pydir) - except Exception, exception: - print "...failed:", exception - break - else: - from xml.dom import minidom - xml = p.communicate()[0] - xml = minidom.parseString(xml) - entries = xml.getElementsByTagName("entry") - if not entries: - if "info" in args: - break - args = ["svn", "info", "-R", "--xml"] - timestamp = None - for entry in iter(entries): - pth = entry.getAttribute("path") - mtime = 0 - if "status" in args: - status = entry.getElementsByTagName("wc-status") - item = status[0].getAttribute("item") - if item.lower() in ("none", "normal"): - item = " " - props = status[0].getAttribute("props") - if props.lower() in ("none", "normal"): - props = " " - print item.upper()[0] + props.upper()[0] + " " * 5, pth - mod = True - if item.upper()[0] != "D" and os.path.exists(pth): - mtime = os.stat(pth).st_mtime - if mtime > lastmod_time: - lastmod_time = mtime - timestamp = time.gmtime(mtime) - schedule = entry.getElementsByTagName("schedule") - if schedule: - schedule = schedule[0].firstChild.wholeText.strip() - if schedule != "normal": - print schedule.upper()[0] + " " * 6, pth - mod = True - mtime = os.stat(pth).st_mtime - if mtime > lastmod_time: - lastmod_time = mtime - timestamp = time.gmtime(mtime) - lmdate = entry.getElementsByTagName("date") - if lmdate: - lmdate = lmdate[0].firstChild.wholeText.strip() - dateparts = lmdate.split(".") # split off milliseconds - mtime = time.mktime(time.strptime(dateparts[0], - "%Y-%m-%dT%H:%M:%S")) - mtime += float("." + strtr(dateparts[1], "Z")) - if mtime > lastmod_time: - lastmod_time = mtime - timestamp = time.localtime(mtime) - if timestamp: - lastmod = strftime("%Y-%m-%dT%H:%M:%S", timestamp) + \ - str(round(mtime - int(mtime), 6))[1:] + \ - "Z" - ## print lmdate, lastmod, pth - - if not dry_run: - print "Generating __version__.py" - versionpy = open(os.path.join(pydir, "DisplayCAL", "__version__.py"), "w") - versionpy.write("# generated by setup.py\n\n") - buildtime = time.time() - versionpy.write("BUILD_DATE = %r\n" % - (strftime("%Y-%m-%dT%H:%M:%S", - gmtime(buildtime)) + - str(round(buildtime - int(buildtime), 6))[1:] + - "Z")) - if lastmod: - versionpy.write("LASTMOD = %r\n" % lastmod) - if svnversion: - if mod: - svnversion = svnversion_bump(svnversion) - else: - print "Version", ".".join(svnversion) - versionpy.write("VERSION = (%s)\n" % ", ".join(svnversion)) - versionpy.write("VERSION_BASE = (%s)\n" % ", ".join(svnbase)) - versionpy.write("VERSION_STRING = %r\n" % ".".join(svnversion)) - versiontxt = open(os.path.join(pydir, "VERSION"), "w") - versiontxt.write(".".join(svnversion)) - versiontxt.close() - versionpy.close() - - if not help and not dry_run: - # Restore setup.cfg.backup if it exists - if os.path.isfile(os.path.join(pydir, "setup.cfg.backup")) and \ - not os.path.isfile(os.path.join(pydir, "setup.cfg")): - shutil.copy2(os.path.join(pydir, "setup.cfg.backup"), - os.path.join(pydir, "setup.cfg")) - - if not sys.argv[1:]: - return - - global name, name_html, author, author_email, description, longdesc - global domain, py_maxversion, py_minversion - global version, version_lin, version_mac - global version_src, version_tuple, version_win - global wx_minversion - from meta import (name, name_html, author, author_email, description, - lastmod, longdesc, domain, py_maxversion, py_minversion, - version, version_lin, version_mac, - version_src, version_tuple, version_win, - wx_minversion, script2pywname) - - if not lastmod_time: - lastmod_time = time.mktime(time.strptime(lastmod, - "%Y-%m-%dT%H:%M:%S.%fZ")) - - msiversion = ".".join((str(version_tuple[0]), - str(version_tuple[1]), - str(version_tuple[2]) + - str(version_tuple[3]))) - - if not dry_run and not help: - if setup_cfg or ("bdist_msi" in sys.argv[1:] and use_setuptools): - if not os.path.exists(os.path.join(pydir, "setup.cfg.backup")): - shutil.copy2(os.path.join(pydir, "setup.cfg"), - os.path.join(pydir, "setup.cfg.backup")) - if "bdist_msi" in sys.argv[1:] and use_setuptools: - # setuptools parses options globally even if they're not under the - # section of the currently run command - os.remove(os.path.join(pydir, "setup.cfg")) - if setup_cfg: - shutil.copy2(os.path.join(pydir, "misc", "setup.%s.cfg" % setup_cfg), - os.path.join(pydir, "setup.cfg")) - - if purge or purge_dist: - - # remove the "build", "DisplayCAL.egg-info" and - # "pyinstaller/bincache*" directories and their contents recursively - - if dry_run: - print "dry run - nothing will be removed" - - paths = [] - if purge: - paths += glob.glob(os.path.join(pydir, "build")) + glob.glob( - os.path.join(pydir, name + ".egg-info")) + glob.glob( - os.path.join(pydir, "pyinstaller", "bincache*")) - sys.argv.remove("purge") - if purge_dist: - paths += glob.glob(os.path.join(pydir, "dist")) - sys.argv.remove("purge_dist") - for path in paths: - if os.path.exists(path): - if dry_run: - print path - continue - try: - shutil.rmtree(path) - except Exception, exception: - print exception - else: - print "removed", path - if len(sys.argv) == 1 or (len(sys.argv) == 2 and dry_run): - return - - if "readme" in sys.argv[1:]: - if not dry_run: - for suffix in ("", "-fr"): - replace_placeholders(os.path.join(pydir, "misc", - "README%s.template.html" % - suffix), - os.path.join(pydir, "README%s.html" % - suffix), - lastmod_time, - {"STABILITY": "Beta" if stability != "stable" - else ""}) - replace_placeholders(os.path.join(pydir, "misc", - "history.template.html"), - os.path.join(pydir, "history.html"), - lastmod_time) - sys.argv.remove("readme") - if len(sys.argv) == 1 or (len(sys.argv) == 2 and dry_run): - return - - if ((appdata or - "install" in sys.argv[1:]) and - not help and not dry_run): - from setup import get_scripts - import localization as lang - scripts = get_scripts() - provides = ["<python2>%s</python2>" % name] - for script, desc in scripts: - provides.append("<binary>%s</binary>" % script) - provides = "\n\t\t".join(provides) - lang.init() - languages = [] - for code, tdict in sorted(lang.ldict.items()): - if code == "en": - continue - untranslated = 0 - for key in tdict: - if key.startswith("*") and key != "*": - untranslated += 1 - languages.append('<lang percentage="%i">%s</lang>' % - (round((1 - untranslated / (len(tdict) - 1.0)) * 100), - code)) - languages = "\n\t\t".join(languages) - tmpl_name = name + ".appdata.xml" - replace_placeholders(os.path.join(pydir, "misc", tmpl_name), - os.path.join(pydir, "dist", tmpl_name), - lastmod_time, {"APPDATAPROVIDES": provides, - "LANGUAGES": languages}) - if appdata: - sys.argv.remove("appdata") - - if (("sdist" in sys.argv[1:] or - "install" in sys.argv[1:] or - "bdist_deb" in sys.argv[1:]) and - not help): - buildservice = True - if buildservice and not dry_run: - replace_placeholders(os.path.join(pydir, "misc", "debian.copyright"), - os.path.join(pydir, "dist", "copyright"), - lastmod_time) - if "buildservice" in sys.argv[1:]: - sys.argv.remove("buildservice") - - if bdist_deb: - bdist_args = ["bdist_rpm"] - if not arch: - arch = get_platform().split("-")[1] - bdist_args += ["--force-arch=" + arch] - i = sys.argv.index("bdist_deb") - sys.argv = sys.argv[:i] + bdist_args + sys.argv[i + 1:] - - if bdist_lipa: - i = sys.argv.index("bdist_lipa") - sys.argv = sys.argv[:i] + sys.argv[i + 1:] - - if bdist_pyi: - i = sys.argv.index("bdist_pyi") - sys.argv = sys.argv[:i] + sys.argv[i + 1:] - if not "build_ext" in sys.argv[1:i]: - sys.argv.insert(i, "build_ext") - if "-F" in sys.argv[1:]: - sys.argv.remove("-F") - if "--onefile" in sys.argv[1:]: - sys.argv.remove("--onefile") - - if inno and sys.platform == "win32": - for tmpl_type in ("pyi" if bdist_pyi else bdist_cmd, "0install", - "0install-per-user"): - inno_template_path = os.path.join(pydir, "misc", "%s-Setup-%s.iss" % - (name, tmpl_type)) - inno_template = open(inno_template_path, "r") - inno_script = inno_template.read().decode("UTF-8", "replace") % { - "AppCopyright": u"© %s %s" % (strftime("%Y"), author), - "AppName": name, - "AppVerName": version, - "AppPublisher": author, - "AppPublisherURL": "http://" + domain, - "AppSupportURL": "http://" + domain, - "AppUpdatesURL": "http://" + domain, - "VersionInfoVersion": ".".join(map(str, version_tuple)), - "VersionInfoTextVersion": version, - "AppVersion": version, - "Platform": get_platform(), - "PythonVersion": sys.version[:3], - "URL": "http://%s/" % domain.lower(), - } - inno_template.close() - inno_path = os.path.join("dist", - os.path.basename(inno_template_path).replace( - bdist_cmd, "%s.%s-py%s" % - (bdist_cmd, get_platform(), - sys.version[:3]))) - if not dry_run: - if not os.path.exists("dist"): - os.makedirs("dist") - inno_file = open(inno_path, "w") - inno_file.write(inno_script.encode("MBCS", "replace")) - inno_file.close() - sys.argv.remove("inno") - if len(sys.argv) == 1 or (len(sys.argv) == 2 and dry_run): - return - - if "finalize_msi" in sys.argv[1:]: - db = msilib.OpenDatabase(r"dist\%s-%s.win32-py%s.msi" % - (name, msiversion, sys.version[:3]), - msilib.MSIDBOPEN_TRANSACT) - view = db.OpenView("SELECT Value FROM Property WHERE Property = 'ProductCode'") - view.Execute(None) - record = view.Fetch() - productcode = record.GetString(1) - view.Close() - msilib.add_data(db, "Directory", [("ProgramMenuFolder", # Directory - "TARGETDIR", # Parent - ".")]) # DefaultDir - msilib.add_data(db, "Directory", [("MenuDir", # Directory - "ProgramMenuFolder", # Parent - name.upper()[:6] + "~1|" + name)]) # DefaultDir - msilib.add_data(db, "Icon", [(name + ".ico", # Name - msilib.Binary(os.path.join(pydir, name, - "theme", "icons", - name + ".ico")))]) # Data - msilib.add_data(db, "Icon", [("uninstall.ico", # Name - msilib.Binary(os.path.join(pydir, name, - "theme", "icons", - name + "-uninstall.ico")))]) # Data - msilib.add_data(db, "RemoveFile", [("MenuDir", # FileKey - name, # Component - None, # FileName - "MenuDir", # DirProperty - 2)]) # InstallMode - msilib.add_data(db, "Registry", [("DisplayIcon", # Registry - -1, # Root - r"Software\Microsoft\Windows\CurrentVersion\Uninstall\%s" % - productcode, # Key - "DisplayIcon", # Name - r"[icons]%s.ico" % name, # Value - name)]) # Component - msilib.add_data(db, "Shortcut", [(name, # Shortcut - "MenuDir", # Directory - name.upper()[:6] + "~1|" + name, # Name - name, # Component - r"[TARGETDIR]pythonw.exe", # Target - r'"[TARGETDIR]Scripts\%s"' % name, # Arguments - None, # Description - None, # Hotkey - name + ".ico", # Icon - None, # IconIndex - None, # ShowCmd - name)]) # WkDir - msilib.add_data(db, "Shortcut", [("LICENSE", # Shortcut - "MenuDir", # Directory - "LICENSE|LICENSE", # Name - name, # Component - r"[%s]LICENSE.txt" % name, # Target - None, # Arguments - None, # Description - None, # Hotkey - None, # Icon - None, # IconIndex - None, # ShowCmd - name)]) # WkDir - msilib.add_data(db, "Shortcut", [("README", # Shortcut - "MenuDir", # Directory - "README|README", # Name - name, # Component - r"[%s]README.html" % name, # Target - None, # Arguments - None, # Description - None, # Hotkey - None, # Icon - None, # IconIndex - None, # ShowCmd - name)]) # WkDir - msilib.add_data(db, "Shortcut", [("Uninstall", # Shortcut - "MenuDir", # Directory - "UNINST|Uninstall", # Name - name, # Component - r"[SystemFolder]msiexec", # Target - r"/x" + productcode, # Arguments - None, # Description - None, # Hotkey - "uninstall.ico", # Icon - None, # IconIndex - None, # ShowCmd - "SystemFolder")]) # WkDir - if not dry_run: - db.Commit() - sys.argv.remove("finalize_msi") - if len(sys.argv) == 1 or (len(sys.argv) == 2 and dry_run): - return - - if zeroinstall: - sys.argv.remove("0install") - - if bdist_appdmg: - sys.argv.remove("bdist_appdmg") - - if (not bdist_lipa and not zeroinstall and not buildservice and - not appdata and not bdist_appdmg) or sys.argv[1:]: - print sys.argv[1:] - from setup import setup - setup() - - if dry_run or help: - return - - if buildservice: - # Create control files - mapping = {"POST": open(os.path.join(pydir, "util", - "rpm_postinstall.sh"), - "r").read().strip(), - "POSTUN": open(os.path.join(pydir, "util", - "rpm_postuninstall.sh"), - "r").read().strip()} - tgz = os.path.join(pydir, "dist", "%s-%s.tar.gz" % (name, version)) - if os.path.isfile(tgz): - with open(tgz, "rb") as tgzfile: - mapping["MD5"] = md5(tgzfile.read()).hexdigest() - for tmpl_name in ("PKGBUILD", "debian.changelog", "debian.control", - "debian.copyright", - "debian.rules", name + ".changes", - name + ".dsc", name + ".spec", - os.path.join("0install", "PKGBUILD"), - os.path.join("0install", "debian.changelog"), - os.path.join("0install", "debian.control"), - os.path.join("0install", "debian.rules"), - os.path.join("0install", name + ".dsc"), - os.path.join("0install", name + ".spec"), - os.path.join("obs-autopackage-deploy", - name + ".spec")): - tmpl_path = os.path.join(pydir, "misc", tmpl_name) - replace_placeholders(tmpl_path, - os.path.join(pydir, "dist", tmpl_name), - lastmod_time, mapping) - - if bdist_deb: - # Read setup.cfg - cfg = RawConfigParser() - cfg.read(os.path.join(pydir, "setup.cfg")) - # Get dependencies - dependencies = [val.strip().split(None, 1) for val in - cfg.get("bdist_rpm", "Requires").split(",")] - # Get group - if cfg.has_option("bdist_rpm", "group"): - group = cfg.get("bdist_rpm", "group") - else: - group = None - # Get maintainer - if cfg.has_option("bdist_rpm", "maintainer"): - maintainer = cfg.get("bdist_rpm", "maintainer") - else: - maintainer = None - # Get packager - if cfg.has_option("bdist_rpm", "packager"): - packager = cfg.get("bdist_rpm", "packager") - else: - packager = None - # Convert dependency format: - # 'package >= version' to 'package (>= version)' - for i in range(len(dependencies)): - if len(dependencies[i]) > 1: - dependencies[i][1] = "(%s)" % dependencies[i][1] - dependencies[i] = " ".join(dependencies[i]) - release = 1 # TODO: parse setup.cfg - rpm_filename = os.path.join(pydir, "dist", "%s-%s-%s.%s.rpm" % - (name, version, release, arch)) - if not dry_run: - # remove target directory (and contents) if it already exists - target_dir = os.path.join(pydir, "dist", "%s-%s" % (name, version)) - if os.path.exists(target_dir): - shutil.rmtree(target_dir) - if os.path.exists(target_dir + ".orig"): - shutil.rmtree(target_dir + ".orig") - # use alien to create deb dir from rpm package - retcode = call(["alien", "-c", "-g", "-k", - os.path.basename(rpm_filename)], - cwd=os.path.join(pydir, "dist")) - if retcode != 0: - sys.exit(retcode) - # update changelog - shutil.copy2(os.path.join(pydir, "dist", "debian.changelog"), - os.path.join(pydir, "dist", "%s-%s" % (name, version), - "debian", "changelog")) - # update rules - shutil.copy2(os.path.join(pydir, "misc", "alien.rules"), - os.path.join(pydir, "dist", "%s-%s" % (name, version), - "debian", "rules")) - # update control - control_filename = os.path.join(pydir, "dist", "%s-%s" % (name, - version), - "debian", "control") - shutil.copy2(os.path.join(pydir, "dist", "debian.control"), - control_filename) - ### read control file from deb dir - ##control = open(control_filename, "r") - ##lines = [line.rstrip("\n") for line in control.readlines()] - ##control.close() - ### update control with info from setup.cfg - ##for i in range(len(lines)): - ##if lines[i].startswith("Depends:"): - ### add dependencies - ##lines[i] += ", python" - ##lines[i] += ", python" + sys.version[:3] - ##lines[i] += ", " + ", ".join(dependencies) - ##elif lines[i].startswith("Maintainer:") and (maintainer or - ##packager): - ### set maintainer - ##lines[i] = "Maintainer: " + (maintainer or packager) - ##elif lines[i].startswith("Section:") and group: - ### set section - ##lines[i] = "Section: " + group - ##elif lines[i].startswith("Description:"): - ##lines.pop() - ##lines.pop() - ##break - ### write updated control file - ##control = open(control_filename, "w") - ##control.write("\n".join(lines)) - ##control.close() - ### run strip on shared libraries - ##sos = os.path.join(change_root(target_dir, get_python_lib(True)), - ##name, "*.so") - ##for so in glob.glob(sos): - ##retcode = call(["strip", "--strip-unneeded", so]) - # create deb package - retcode = call(["chmod", "+x", "./debian/rules"], cwd=target_dir) - retcode = call(["./debian/rules", "binary"], cwd=target_dir) - if retcode != 0: - sys.exit(retcode) - - if setup_cfg or ("bdist_msi" in sys.argv[1:] and use_setuptools): - shutil.copy2(os.path.join(pydir, "setup.cfg.backup"), - os.path.join(pydir, "setup.cfg")) - - if bdist_lipa: - # Create a Listaller package using lipkgen - from setup import get_data, get_scripts - scripts = get_scripts() - ipkinstall = os.path.join(pydir, "ipkinstall") - # Generate doap file - replace_placeholders(os.path.join(pydir, "misc", name + ".doap"), - os.path.join(ipkinstall, name + ".doap"), - lastmod_time) - # Adjust .desktop files - for script, desc in scripts: - filename = os.path.join(pydir, "misc", script + ".desktop") - if os.path.exists(filename): - with open(filename) as file1: - filename = os.path.join(ipkinstall, script + ".desktop") - with open(filename, "w") as file2: - file2.write(file1.read().replace("Exec=" + script, - "Exec=%s.pyw" % - script2pywname(script))) - # Collect data - collect = ([("%APP%", ["ipkinstall/%s.desktop" % script - for script, desc in - filter(lambda (script, desc): - not script.endswith("-apply-profiles"), - scripts)])] + - [("%%ICON-%s%%" % size, - ["%s/theme/icons/%sx%s/%s.png" % - (name, size, size, script) - for script, desc in scripts]) - for size in (16, 24, 32, 48, 64, 128, 256)] + - [("%INST%", ["%s.pyw" % script2pywname(script) - for script, desc in scripts])] + - get_data("%INST%", "data") + - get_data("%INST%", "doc") + - [("%INST%/" + name, - glob.glob(os.path.join(name, "*.py")))] + - [("%%INST%%/%s/lib" % name, - glob.glob(os.path.join(name, "lib/*.py")))] + - [("%%INST%%/%s/lib/agw" % name, - glob.glob(os.path.join(name, "lib/agw/*.py")))] + - get_data("%INST%/" + name, "package_data", name) + - [("%INST%/scripts", ["scripts/%s" % script - for script, desc in scripts])]) - for bits in (32, 64): - collect += [("%%INST%%/%s/lib%s" % (name, bits), - glob.glob(os.path.join(name, "lib%s/*.py" % bits)))] - for pycompat in (26, 27): - collect += [("%%INST%%/%s/lib%s/python%s" - % (name, bits, pycompat), - glob.glob(os.path.join(name, "lib%s/python%s/*.py" - % (bits, pycompat))) + - glob.glob(os.path.join(name, "lib%s/python%s/*.so" - % (bits, pycompat))))] - data = {} - for tgt_dir, files in collect: - tgt_dir = tgt_dir.replace(os.sep, "/") - if not tgt_dir in data: - data[tgt_dir] = [] - data[tgt_dir] += files - tgt_dirs = sorted(data.keys()) - # Generate files list - with open(os.path.join(ipkinstall, "files-all.list"), "w") as fileslist: - fileslist.write("# IPK file list for %s\n" % name) - fileslist.write("# Generated by setup.py, do not edit\n") - fileslist.write("\n") - cur_tgt_dir = None - for tgt_dir in tgt_dirs: - if tgt_dir != cur_tgt_dir: - cur_tgt_dir = tgt_dir - fileslist.write(":: %s\n" % tgt_dir) - for filename in sorted(data[tgt_dir]): - fileslist.write(os.path.relpath(filename, - pydir).replace(os.sep, - "/") + "\n") - # Create actual Listaller package - if not which("lipkgen"): - raise SystemExit("Error: No lipkgen in %s" % os.getenv("PATH")) - out_dir = os.path.join(pydir, "dist") - if not os.path.isdir(out_dir): - os.makedirs(out_dir) - retcode = call(["lipkgen", "-b", "-o", out_dir, "--sign"]) - if retcode != 0: - sys.exit(retcode) - - if bdist_pyi: - - # create an executable using pyinstaller - - retcode = call([sys.executable, os.path.join(pydir, "pyinstaller", - "pyinstaller.py"), - "--workpath", os.path.join(pydir, "build", - "pyi.%s-%s" % - (get_platform(), - sys.version[:3])), - "--distpath", os.path.join(pydir, "dist", - "pyi.%s-py%s" % - (get_platform(), - sys.version[:3])), - os.path.join(pydir, "misc", "%s.pyi.spec" % name)]) - if retcode != 0: - sys.exit(retcode) - - if zeroinstall: - from xml.dom import minidom - # Create/update 0install feeds - from setup import get_data, get_scripts - scripts = sorted((script2pywname(script), desc) - for script, desc in get_scripts()) - cmds = [] - for script, desc in scripts: - cmdname = "run" - if script != name: - cmdname += "-" + script.replace(name + "-", "") - cmds.append((cmdname, script, desc)) - ##if script.endswith("-apply-profiles"): - ### Add forced calibration loading entry - ##cmds.append((cmdname + "-force", script, desc)) - # Get archive digest - extract = "%s-%s" % (name, version) - archive_name = extract + ".tar.gz" - archive_path = os.path.join(pydir, "dist", archive_name) - p = Popen(["0install", "digest", archive_path.encode(fs_enc), extract], - stdout=sp.PIPE, cwd=pydir) - stdout, stderr = p.communicate() - print stdout - hash = re.search("(sha\d+\w+[=_][0-9a-f]+)", stdout.strip()) - if not hash: - raise SystemExit(p.wait()) - hash = hash.groups()[0] - for tmpl_name in ("7z.xml", "argyllcms.xml", name + ".xml", - name + "-linux.xml", name + "-mac.xml", - name + "-win32.xml", "numpy.xml", "pygame.xml", - "pywin32.xml", "wmi.xml", "wxpython.xml"): - dist_path = os.path.join(pydir, "dist", "0install", tmpl_name) - create = not os.path.isfile(dist_path) - if create: - tmpl_path = os.path.join(pydir, "misc", "0install", - tmpl_name) - replace_placeholders(tmpl_path, dist_path, lastmod_time) - if tmpl_name.startswith(name): - with open(dist_path) as dist_file: - xml = dist_file.read() - domtree = minidom.parseString(xml) - # Get interface - interface = domtree.getElementsByTagName("interface")[0] - # Get languages - langs = [os.path.splitext(os.path.basename(lang))[0] for lang in - glob.glob(os.path.join(name, "lang", "*.json"))] - # Get architecture groups - groups = domtree.getElementsByTagName("group") - if groups: - # Get main group - group0 = groups[0] - # Add languages - group0.setAttribute("langs", " ".join(langs)) - # Update groups - for i, group in enumerate(groups[-1:]): - if create: - # Remove dummy implementations - for implementation in group.getElementsByTagName("implementation"): - if implementation.getAttribute("released") == "0000-00-00": - implementation.parentNode.removeChild(implementation) - # Add commands - runner = domtree.createElement("runner") - if group.getAttribute("arch").startswith("Windows-"): - runner.setAttribute("command", "run-win") - if group.getAttribute("arch").startswith("Linux"): - python = "http://repo.roscidus.com/python/python" - else: - python = "http://%s/0install/python.xml" % domain.lower() - runner.setAttribute("interface", python) - runner.setAttribute("version", - "%i.%i..!3.0" % py_minversion) - for cmdname, script, desc in cmds: - # Add command to group - cmd = domtree.createElement("command") - cmd.setAttribute("name", cmdname) - cmd.setAttribute("path", script + ".pyw") - ##if cmdname.endswith("-apply-profiles"): - ### Autostart - ##arg = domtree.createElement("suggest-auto-start") - ##cmd.appendChild(arg) - if cmdname.endswith("-apply-profiles-force"): - # Forced calibration loading - arg = domtree.createElement("arg") - arg.appendChild(domtree.createTextNode("--force")) - cmd.appendChild(arg) - cmd.appendChild(runner.cloneNode(True)) - group.appendChild(cmd) - # Add implementation if it does not exist yet, update otherwise - match = None - for implementation in group.getElementsByTagName("implementation"): - match = (implementation.getAttribute("version") == version and - implementation.getAttribute("stability") == stability) - if match: - break - if not match: - implementation = domtree.createElement("implementation") - implementation.setAttribute("version", version) - implementation.setAttribute("released", - strftime("%Y-%m-%d", - gmtime(lastmod_time))) - implementation.setAttribute("stability", stability) - digest = domtree.createElement("manifest-digest") - implementation.appendChild(digest) - archive = domtree.createElement("archive") - implementation.appendChild(archive) - else: - digest = implementation.getElementsByTagName("manifest-digest")[0] - for attrname, value in digest.attributes.items(): - # Remove existing hashes - digest.removeAttribute(attrname) - archive = implementation.getElementsByTagName("archive")[0] - implementation.setAttribute("id", hash) - digest.setAttribute(*hash.split("=")) - # Update archive - if stability == "stable": - folder = "" - else: - folder = "&folder=snapshot" - archive.setAttribute("extract", extract) - archive.setAttribute("href", - "http://%s/download.php?version=%s&suffix=.tar.gz%s" % - (domain.lower(), version, folder)) - archive.setAttribute("size", "%s" % os.stat(archive_path).st_size) - archive.setAttribute("type", "application/x-compressed-tar") - group.appendChild(implementation) - if create: - for cmdname, script, desc in cmds: - # Add entry-points to interface - entry_point = domtree.createElement("entry-point") - entry_point.setAttribute("command", cmdname) - binname = script - if cmdname.endswith("-force"): - binname += "-force" - entry_point.setAttribute("binary-name", binname) - cfg = RawConfigParser() - desktopbasename = "%s.desktop" % script - if cmdname.endswith("-apply-profiles"): - desktopbasename = "z-" + desktopbasename - cfg.read(os.path.join(pydir, "misc", - desktopbasename)) - for option, tagname in (("Name", "name"), - ("GenericName", "summary"), - ("Comment", "description")): - for lang in [None] + langs: - if lang: - suffix = "[%s]" % lang - else: - suffix = "" - option = "%s%s" % (option, suffix) - if cfg.has_option("Desktop Entry", option): - value = cfg.get("Desktop Entry", - option).decode("UTF-8") - if value: - tag = domtree.createElement(tagname) - if not lang: - lang = "en" - tag.setAttribute("xml:lang", lang) - tag.appendChild(domtree.createTextNode(value)) - entry_point.appendChild(tag) - for ext, mime_type in (("ico", "image/vnd.microsoft.icon"), - ("png", "image/png")): - icon = domtree.createElement("icon") - if ext == "ico": - subdir = "" - filename = script - else: - subdir = "256x256/" - filename = script.lower() - icon.setAttribute("href", - "http://%s/theme/icons/%s%s.%s" % - (domain.lower(), subdir, - filename, ext)) - icon.setAttribute("type", mime_type) - entry_point.appendChild(icon) - interface.appendChild(entry_point) - # Update feed - print "Updating 0install feed", dist_path - with open(dist_path, "wb") as dist_file: - xml = domtree.toprettyxml(encoding="utf-8") - xml = re.sub(r"\n\s+\n", "\n", xml) - xml = re.sub(r"\n\s*([^<]+)\n\s*", r"\1", xml) - dist_file.write(xml) - # Sign feed - zeropublish = which("0publish") or which("0publish.exe") - args = [] - if not zeropublish: - zeropublish = which("0install") or which("0install.exe") - if zeropublish: - args = ["run", "--command", "0publish", "--", - "http://0install.de/feeds/ZeroInstall_Tools.xml"] - if zeropublish: - passphrase_path = os.path.join(pydir, "gpg", "passphrase.txt") - print "Signing", dist_path - if os.path.isfile(passphrase_path): - import wexpect - with open(passphrase_path) as passphrase_file: - passphrase = passphrase_file.read().strip() - p = wexpect.spawn(zeropublish.encode(fs_enc), args + - ["-x", dist_path.encode(fs_enc)]) - p.expect(":") - p.send(passphrase) - p.send("\n") - try: - p.expect(wexpect.EOF, timeout=3) - except: - p.terminate() - else: - call([zeropublish] + args + ["-x", dist_path.encode(fs_enc)]) - else: - print "WARNING: 0publish not found, please sign the feed!" - # Create 0install app bundles - bundletemplate = os.path.join("0install", "template.app", "Contents") - bundletemplatepath = os.path.join(pydir, bundletemplate) - if os.path.isdir(bundletemplatepath): - p = Popen(["0install", "-V"], stdout=sp.PIPE) - stdout, stderr = p.communicate() - zeroinstall_version = re.search(r" (\d(?:\.\d+)+)", stdout) - if zeroinstall_version: - zeroinstall_version = zeroinstall_version.groups()[0] - if zeroinstall_version < "2.8": - zeroinstall_version = "2.8" - feeduri = "http://%s/0install/%s.xml" % (domain.lower(), name) - dist_dir = os.path.join(pydir, "dist", "0install", - name + "-0install") - for script, desc in scripts + [("0install-launcher", - "0install Launcher"), - ("0install-cache-manager", - "0install Cache Manager")]: - if script.endswith("-apply-profiles"): - continue - desc = re.sub("^%s " % name, "", desc).strip() - if script == "0install-launcher": - bundlename = name - else: - bundlename = desc - bundledistpath = os.path.join(dist_dir, desc + ".app", - "Contents") - replace_placeholders(os.path.join(bundletemplatepath, - "Info.plist"), - os.path.join(bundledistpath, - "Info.plist"), lastmod_time, - {"NAME": bundlename, - "EXECUTABLE": script, - "ID": ".".join(reversed(domain.split("."))).replace(name, - script)}) - if script.startswith(name): - run = "0launch%s -- %s" % (re.sub("^%s" % name, - " --command=run", script), - feeduri) - else: - run = {"0install-launcher": "0launch --gui " + feeduri, - "0install-cache-manager": "0store manage"}.get(script) - replace_placeholders(os.path.join(bundletemplatepath, "MacOS", - "template"), - os.path.join(bundledistpath, - "MacOS", script), - lastmod_time, - {"EXEC": run, - "ZEROINSTALL_VERSION": zeroinstall_version}) - os.chmod(os.path.join(bundledistpath, "MacOS", script), 0755) - for binary in os.listdir(os.path.join(bundletemplatepath, - "MacOS")): - if binary == "template": - continue - src = os.path.join(bundletemplatepath, "MacOS", binary) - dst = os.path.join(bundledistpath, "MacOS", binary) - if os.path.islink(src): - linkto = os.readlink(src) - if os.path.islink(dst) and os.readlink(dst) != linkto: - os.remove(dst) - if not os.path.islink(dst): - os.symlink(linkto, dst) - else: - shutil.copy2(src, dst) - resdir = os.path.join(bundledistpath, "Resources") - if not os.path.isdir(resdir): - os.mkdir(resdir) - if script.startswith(name): - iconsrc = os.path.join(pydir, name, "theme", "icons", - script + ".icns") - else: - iconsrc = os.path.join(pydir, "0install", - "ZeroInstall.icns") - icondst = os.path.join(resdir, script + ".icns") - if os.path.isfile(iconsrc) and not os.path.isfile(icondst): - shutil.copy2(iconsrc, icondst) - # README as .webloc file (link to homepage) - with codecs.open(os.path.join(dist_dir, "README.webloc"), "w", - "UTF-8") as readme: - readme.write("""<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>URL</key> - <string>http://%s/</string> -</dict> -</plist> -""" % domain.lower()) - # Copy LICENSE.txt - shutil.copy2(os.path.join(pydir, "LICENSE.txt"), - os.path.join(dist_dir, "LICENSE.txt")) - - if bdist_appdmg: - create_appdmg(zeroinstall) - - -if __name__ == "__main__": - setup() --- a/.pc/applied-patches 2016-08-24 23:08:44.542458026 +0100 --- b/.pc/applied-patches 1970-01-01 01:00:00.000000000 +0100 @@ -1 +0,0 @@ -01_reproducible-build.diff --- a/debian/patches/01_reproducible-build.diff 2016-08-24 23:08:44.478457355 +0100 --- b/debian/patches/01_reproducible-build.diff 2016-08-24 23:30:15.100269789 +0100 @@ -1,11 +1,24 @@ ---- a/setup.py -+++ b/setup.py +Description: Make the build reproducible +Author: Chris Lamb <la...@debian.org> +Last-Update: 2016-08-24 + +--- dispcalgui-3.1.5.0.orig/setup.py ++++ dispcalgui-3.1.5.0/setup.py +@@ -80,7 +80,7 @@ def replace_placeholders(tmpl_path, out_ + strftime("%H:%M", + gmtime(lastmod_time or + os.stat(tmpl_path).st_mtime)), +- "TIMESTAMP": str(int(lastmod_time)), ++ "TIMESTAMP": str(int(os.environ.get('SOURCE_DATE_EPOCH', lastmod_time))), + "SUMMARY": description, + "DESC": longdesc, + "APPDATADESC": "<p>\n\t\t\t" + longdesc.replace("\n", "\n\t\t\t").replace(".\n", ".\n\t\t</p>\n\t\t<p>\n") + "\n\t\t</p>", @@ -99,7 +99,7 @@ def replace_placeholders(tmpl_path, out_ "VERSION_SHORT": re.sub("(?:\.0){1,2}$", "", version), "URL": "http://%s/" % domain.lower(), "WX_MINVERSION": ".".join(str(n) for n in wx_minversion), - "YEAR": strftime("%Y", gmtime())} -+ "YEAR": strftime("%Y", gmtime(lastmod_time or os.stat(tmpl_path).st_mtime))} ++ "YEAR": strftime("%Y", gmtime(int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))))} mapping.update(iterable or {}) for key, val in mapping.iteritems(): tmpl_data = tmpl_data.replace("${%s}" % key, val) --- a/setup.py 2016-08-24 23:08:44.478457355 +0100 --- b/setup.py 2016-08-24 23:27:35.000000000 +0100 @@ -99,7 +99,7 @@ "VERSION_SHORT": re.sub("(?:\.0){1,2}$", "", version), "URL": "http://%s/" % domain.lower(), "WX_MINVERSION": ".".join(str(n) for n in wx_minversion), - "YEAR": strftime("%Y", gmtime(lastmod_time or os.stat(tmpl_path).st_mtime))} + "YEAR": strftime("%Y", gmtime())} mapping.update(iterable or {}) for key, val in mapping.iteritems(): tmpl_data = tmpl_data.replace("${%s}" % key, val)