From 7a45b9a0e2275a038db2945e1ac2c2e426e94344 Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Sun, 12 Jan 2014 10:35:31 -0500 Subject: [PATCH 1/5] Reorganized setup.py code Added "deb" setup command --- .gitignore | 3 + setup.py | 230 ++++++++++++++++++++----------------- tools/generateChangelog.py | 122 ++++++++++---------- tools/setupHelpers.py | 114 ++++++++++++++++++ 4 files changed, 304 insertions(+), 165 deletions(-) create mode 100644 tools/setupHelpers.py diff --git a/.gitignore b/.gitignore index 28ed45aa..b8e7af73 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,6 @@ __pycache__ build *.pyc *.swp +MANIFEST +deb_build +dist diff --git a/setup.py b/setup.py index 826bb57c..761a090d 100644 --- a/setup.py +++ b/setup.py @@ -1,105 +1,4 @@ -from distutils.core import setup -import distutils.dir_util -import os, sys, re -from subprocess import check_output - -## generate list of all sub-packages -path = os.path.abspath(os.path.dirname(__file__)) -n = len(path.split(os.path.sep)) -subdirs = [i[0].split(os.path.sep)[n:] for i in os.walk(os.path.join(path, 'pyqtgraph')) if '__init__.py' in i[2]] -all_packages = ['.'.join(p) for p in subdirs] + ['pyqtgraph.examples'] - - -## Make sure build directory is clean before installing -buildPath = os.path.join(path, 'build') -if os.path.isdir(buildPath): - distutils.dir_util.remove_tree(buildPath) - - -## Determine current version string -initfile = os.path.join(path, 'pyqtgraph', '__init__.py') -init = open(initfile).read() -m = re.search(r'__version__ = (\S+)\n', init) -if m is None or len(m.groups()) != 1: - raise Exception("Cannot determine __version__ from init file: '%s'!" % initfile) -version = m.group(1).strip('\'\"') -initVersion = version - -# If this is a git checkout, try to generate a more decriptive version string -try: - if os.path.isdir(os.path.join(path, '.git')): - def gitCommit(name): - commit = check_output(['git', 'show', name], universal_newlines=True).split('\n')[0] - assert commit[:7] == 'commit ' - return commit[7:] - - # Find last tag matching "pyqtgraph-.*" - tagNames = check_output(['git', 'tag'], universal_newlines=True).strip().split('\n') - while True: - if len(tagNames) == 0: - raise Exception("Could not determine last tagged version.") - lastTagName = tagNames.pop() - if re.match(r'pyqtgraph-.*', lastTagName): - break - - # is this commit an unchanged checkout of the last tagged version? - lastTag = gitCommit(lastTagName) - head = gitCommit('HEAD') - if head != lastTag: - branch = re.search(r'\* (.*)', check_output(['git', 'branch'], universal_newlines=True)).group(1) - version = version + "-%s-%s" % (branch, head[:10]) - - # any uncommitted modifications? - modified = False - status = check_output(['git', 'status', '-s'], universal_newlines=True).strip().split('\n') - for line in status: - if line[:2] != '??': - modified = True - break - - if modified: - version = version + '+' - sys.stderr.write("Detected git commit; will use version string: '%s'\n" % version) -except: - version = initVersion - sys.stderr.write("This appears to be a git checkout, but an error occurred " - "while attempting to determine a version string for the " - "current commit.\nUsing the unmodified version string " - "instead: '%s'\n" % version) - sys.excepthook(*sys.exc_info()) - - -import distutils.command.build - -class Build(distutils.command.build.build): - def run(self): - ret = distutils.command.build.build.run(self) - - # If the version in __init__ is different from the automatically-generated - # version string, then we will update __init__ in the build directory - global path, version, initVersion - if initVersion == version: - return ret - - initfile = os.path.join(path, self.build_lib, 'pyqtgraph', '__init__.py') - if not os.path.isfile(initfile): - sys.stderr.write("Warning: setup detected a git install and attempted " - "to generate a descriptive version string; however, " - "the expected build file at %s was not found. " - "Installation will use the original version string " - "%s instead.\n" % (initfile, initVersion) - ) - else: - data = open(initfile, 'r').read() - open(initfile, 'w').write(re.sub(r"__version__ = .*", "__version__ = '%s'" % version, data)) - return ret - - -setup(name='pyqtgraph', - version=version, - cmdclass={'build': Build}, - description='Scientific Graphics and GUI Library for Python', - long_description="""\ +DESCRIPTION = """\ PyQtGraph is a pure-python graphics and GUI library built on PyQt4/PySide and numpy. @@ -107,14 +6,16 @@ It is intended for use in mathematics / scientific / engineering applications. Despite being written entirely in python, the library is very fast due to its heavy leverage of numpy for number crunching, Qt's GraphicsView framework for 2D display, and OpenGL for 3D display. -""", +""" + +setupOpts = dict( + name='pyqtgraph', + description='Scientific Graphics and GUI Library for Python', + long_description=DESCRIPTION, license='MIT', url='http://www.pyqtgraph.org', author='Luke Campagnola', author_email='luke.campagnola@gmail.com', - packages=all_packages, - package_dir={'pyqtgraph.examples': 'examples'}, ## install examples along with the rest of the source - #package_data={'pyqtgraph': ['graphicsItems/PlotItem/*.png']}, classifiers = [ "Programming Language :: Python", "Programming Language :: Python :: 2", @@ -130,9 +31,126 @@ heavy leverage of numpy for number crunching, Qt's GraphicsView framework for "Topic :: Scientific/Engineering :: Visualization", "Topic :: Software Development :: User Interfaces", ], +) + + +from distutils.core import setup +import distutils.dir_util +import os, sys, re + +path = os.path.split(__file__)[0] +sys.path.insert(0, os.path.join(path, 'tools')) +import setupHelpers as helpers + +## generate list of all sub-packages +allPackages = helpers.listAllPackages(pkgroot='pyqtgraph') + ['pyqtgraph.examples'] + +## Decide what version string to use in the build +version, forcedVersion, gitVersion, initVersion = helpers.getVersionStrings(pkg='pyqtgraph') + + +import distutils.command.build + +class Build(distutils.command.build.build): + """ + * Clear build path before building + * Set version string in __init__ after building + """ + def run(self): + global path, version, initVersion, forcedVersion + global buildVersion + + ## Make sure build directory is clean + buildPath = os.path.join(path, self.build_lib) + if os.path.isdir(buildPath): + distutils.dir_util.remove_tree(buildPath) + + ret = distutils.command.build.build.run(self) + + # If the version in __init__ is different from the automatically-generated + # version string, then we will update __init__ in the build directory + if initVersion == version: + return ret + + try: + initfile = os.path.join(buildPath, 'pyqtgraph', '__init__.py') + data = open(initfile, 'r').read() + open(initfile, 'w').write(re.sub(r"__version__ = .*", "__version__ = '%s'" % version, data)) + buildVersion = version + except: + if forcedVersion: + raise + buildVersion = initVersion + sys.stderr.write("Warning: Error occurred while setting version string in build path. " + "Installation will use the original version string " + "%s instead.\n" % (initVersion) + ) + sys.excepthook(*sys.exc_info()) + return ret + +from distutils.core import Command +import shutil, subprocess + +class DebCommand(Command): + description = "build .deb package" + user_options = [] + def initialize_options(self): + self.cwd = None + def finalize_options(self): + self.cwd = os.getcwd() + def run(self): + assert os.getcwd() == self.cwd, 'Must be in package root: %s' % self.cwd + global version + pkgName = "python-pyqtgraph-" + version + debDir = "deb_build" + if os.path.isdir(debDir): + raise Exception('DEB build dir already exists: "%s"' % debDir) + sdist = "dist/pyqtgraph-%s.tar.gz" % version + if not os.path.isfile(sdist): + raise Exception("No source distribution; run `setup.py sdist` first.") + + # copy sdist to build directory and extract + os.mkdir(debDir) + renamedSdist = 'python-pyqtgraph_%s.orig.tar.gz' % version + shutil.copy(sdist, os.path.join(debDir, renamedSdist)) + if os.system("cd %s; tar -xzf %s" % (debDir, renamedSdist)) != 0: + raise Exception("Error extracting source distribution.") + buildDir = '%s/pyqtgraph-%s' % (debDir, version) + + # copy debian control structure + shutil.copytree('tools/debian', buildDir+'/debian') + + # Write changelog + #chlog = subprocess.check_output([sys.executable, 'tools/generateChangelog.py', 'CHANGELOG']) + #open('%s/pyqtgraph-%s/debian/changelog', 'w').write(chlog) + if os.system('python tools/generateChangelog.py CHANGELOG %s > %s/debian/changelog' % (version, buildDir)) != 0: + raise Exception("Error writing debian/changelog") + + # build package + if os.system('cd %s; debuild -us -uc' % buildDir) != 0: + raise Exception("Error during debuild.") + +class TestCommand(Command): + description = "" + user_options = [] + def initialize_options(self): + pass + def finalize_options(self): + pass + def run(self): + global cmd + cmd = self + +setup( + version=version, + cmdclass={'build': Build, 'deb': DebCommand, 'test': TestCommand}, + packages=allPackages, + package_dir={'pyqtgraph.examples': 'examples'}, ## install examples along with the rest of the source + #package_data={'pyqtgraph': ['graphicsItems/PlotItem/*.png']}, install_requires = [ 'numpy', 'scipy', ], + **setupOpts ) diff --git a/tools/generateChangelog.py b/tools/generateChangelog.py index 0c8bf3e6..32c9ad2c 100644 --- a/tools/generateChangelog.py +++ b/tools/generateChangelog.py @@ -1,66 +1,70 @@ -from subprocess import check_output -import re, time +import re, time, sys +if len(sys.argv) < 3: + sys.stderr.write("Must specify changelog file and latest release!\n") + sys.exit(-1) -def run(cmd): - return check_output(cmd, shell=True) +### Convert CHANGELOG format like: +""" +pyqtgraph-0.9.1 2012-12-29 -tags = run('bzr tags') -versions = [] -for tag in tags.split('\n'): - if tag.strip() == '': - continue - ver, rev = re.split(r'\s+', tag) - if ver.startswith('pyqtgraph-'): - versions.append(ver) + - change + - change +""" -for i in range(len(versions)-1)[::-1]: - log = run('bzr log -r tag:%s..tag:%s' % (versions[i], versions[i+1])) - changes = [] - times = [] - inmsg = False - for line in log.split('\n'): - if line.startswith('message:'): - inmsg = True - continue - elif line.startswith('-----------------------'): - inmsg = False - continue - - if inmsg: - changes.append(line) - else: - m = re.match(r'timestamp:\s+(.*)$', line) - if m is not None: - times.append(m.groups()[0]) - - citime = time.strptime(times[0][:-6], '%a %Y-%m-%d %H:%M:%S') - - print "python-pyqtgraph (%s-1) UNRELEASED; urgency=low" % versions[i+1].split('-')[1] - print "" - for line in changes: - for n in range(len(line)): - if line[n] != ' ': - n += 1 - break - - words = line.split(' ') - nextline = '' - for w in words: - if len(w) + len(nextline) > 79: - print nextline - nextline = (' '*n) + w - else: - nextline += ' ' + w - print nextline - #print '\n'.join(changes) - print "" - print " -- Luke %s -0%d00" % (time.strftime('%a, %d %b %Y %H:%M:%S', citime), time.timezone/3600) - #print " -- Luke %s -0%d00" % (times[0], time.timezone/3600) - print "" - -print """python-pyqtgraph (0.9.0-1) UNRELEASED; urgency=low +### to debian changelog format: +""" +python-pyqtgraph (0.9.1-1) UNRELEASED; urgency=low * Initial release. - -- Luke Thu, 27 Dec 2012 02:46:26 -0500""" + -- Luke Sat, 29 Dec 2012 01:07:23 -0500 +""" + + + +releases = [] +current_version = None +current_log = None +current_date = None +for line in open(sys.argv[1]).readlines(): + match = re.match(r'pyqtgraph-(\d+\.\d+\.\d+(\.\d+)?)\s*(\d+-\d+-\d+)\s*$', line) + if match is None: + if current_log is not None: + current_log.append(line) + else: + if current_log is not None: + releases.append((current_version, current_log, current_date)) + current_version, current_date = match.groups()[0], match.groups()[2] + #sys.stderr.write("Found release %s\n" % current_version) + current_log = [] + +if releases[0][0] != sys.argv[2]: + sys.stderr.write("Latest release in changelog (%s) does not match current release (%s)\n" % (releases[0][0], sys.argv[2])) + sys.exit(-1) + +for release, changes, date in releases: + date = time.strptime(date, '%Y-%m-%d') + changeset = [ + "python-pyqtgraph (%s-1) UNRELEASED; urgency=low\n" % release, + "\n"] + changes + [ + " -- Luke %s -0%d00\n" % (time.strftime('%a, %d %b %Y %H:%M:%S', date), time.timezone/3600), + "\n" ] + + # remove consecutive blank lines except between releases + clean = "" + lastBlank = True + for line in changeset: + if line.strip() == '': + if lastBlank: + continue + else: + clean += line + lastBlank = True + else: + clean += line + lastBlank = False + + print clean + print "" + diff --git a/tools/setupHelpers.py b/tools/setupHelpers.py new file mode 100644 index 00000000..216e6cc2 --- /dev/null +++ b/tools/setupHelpers.py @@ -0,0 +1,114 @@ +import os, sys, re +from subprocess import check_output + +def listAllPackages(pkgroot): + path = os.getcwd() + n = len(path.split(os.path.sep)) + subdirs = [i[0].split(os.path.sep)[n:] for i in os.walk(os.path.join(path, pkgroot)) if '__init__.py' in i[2]] + return ['.'.join(p) for p in subdirs] + + +def getInitVersion(pkgroot): + """Return the version string defined in __init__.py""" + path = os.getcwd() + initfile = os.path.join(path, pkgroot, '__init__.py') + init = open(initfile).read() + m = re.search(r'__version__ = (\S+)\n', init) + if m is None or len(m.groups()) != 1: + raise Exception("Cannot determine __version__ from init file: '%s'!" % initfile) + version = m.group(1).strip('\'\"') + return version + +def gitCommit(name): + """Return the commit ID for the given name.""" + commit = check_output(['git', 'show', name], universal_newlines=True).split('\n')[0] + assert commit[:7] == 'commit ' + return commit[7:] + +def getGitVersion(tagPrefix): + """Return a version string with information about this git checkout. + If the checkout is an unmodified, tagged commit, then return the tag version. + If this is not a tagged commit, return version-branch_name-commit_id. + If this checkout has been modified, append "+" to the version. + """ + path = os.getcwd() + if not os.path.isdir(os.path.join(path, '.git')): + return None + + # Find last tag matching "tagPrefix.*" + tagNames = check_output(['git', 'tag'], universal_newlines=True).strip().split('\n') + while True: + if len(tagNames) == 0: + raise Exception("Could not determine last tagged version.") + lastTagName = tagNames.pop() + if re.match(tagPrefix+r'\d+\.\d+.*', lastTagName): + break + gitVersion = lastTagName.replace(tagPrefix, '') + + # is this commit an unchanged checkout of the last tagged version? + lastTag = gitCommit(lastTagName) + head = gitCommit('HEAD') + if head != lastTag: + branch = re.search(r'\* (.*)', check_output(['git', 'branch'], universal_newlines=True)).group(1) + gitVersion = gitVersion + "-%s-%s" % (branch, head[:10]) + + # any uncommitted modifications? + modified = False + status = check_output(['git', 'status', '-s'], universal_newlines=True).strip().split('\n') + for line in status: + if line[:2] != '??': + modified = True + break + + if modified: + gitVersion = gitVersion + '+' + + return gitVersion + +def getVersionStrings(pkg): + """ + Returns 4 version strings: + + * the version string to use for this build, + * version string requested with --force-version (or None) + * version string that describes the current git checkout (or None). + * version string in the pkg/__init__.py, + + The first return value is (forceVersion or gitVersion or initVersion). + """ + + ## Determine current version string from __init__.py + initVersion = getInitVersion(pkgroot='pyqtgraph') + + ## If this is a git checkout, try to generate a more descriptive version string + try: + gitVersion = getGitVersion(tagPrefix='pyqtgraph-') + except: + gitVersion = None + sys.stderr.write("This appears to be a git checkout, but an error occurred " + "while attempting to determine a version string for the " + "current commit.\n") + sys.excepthook(*sys.exc_info()) + + # See whether a --force-version flag was given + forcedVersion = None + for i,arg in enumerate(sys.argv): + if arg.startswith('--force-version'): + if arg == '--force-version': + forcedVersion = sys.argv[i+1] + sys.argv.pop(i) + sys.argv.pop(i) + elif arg.startswith('--force-version='): + forcedVersion = sys.argv[i].replace('--force-version=', '') + sys.argv.pop(i) + + ## Finally decide on a version string to use: + if forcedVersion is not None: + version = forcedVersion + elif gitVersion is not None: + version = gitVersion + sys.stderr.write("Detected git commit; will use version string: '%s'\n" % version) + else: + version = initVersion + + return version, forcedVersion, gitVersion, initVersion \ No newline at end of file From 9a131f763b698936818c3069b65d6f036c362018 Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Sun, 12 Jan 2014 11:50:52 -0500 Subject: [PATCH 2/5] more reorganization to make setup-helpers code more generic --- setup.py | 55 +--------------- tools/debian/control | 2 +- tools/generateChangelog.py | 128 ++++++++++++++++++++----------------- tools/setupHelpers.py | 70 +++++++++++++++++++- 4 files changed, 141 insertions(+), 114 deletions(-) diff --git a/setup.py b/setup.py index 761a090d..16d66f61 100644 --- a/setup.py +++ b/setup.py @@ -59,7 +59,7 @@ class Build(distutils.command.build.build): def run(self): global path, version, initVersion, forcedVersion global buildVersion - + ## Make sure build directory is clean buildPath = os.path.join(path, self.build_lib) if os.path.isdir(buildPath): @@ -88,62 +88,11 @@ class Build(distutils.command.build.build): sys.excepthook(*sys.exc_info()) return ret -from distutils.core import Command -import shutil, subprocess -class DebCommand(Command): - description = "build .deb package" - user_options = [] - def initialize_options(self): - self.cwd = None - def finalize_options(self): - self.cwd = os.getcwd() - def run(self): - assert os.getcwd() == self.cwd, 'Must be in package root: %s' % self.cwd - global version - pkgName = "python-pyqtgraph-" + version - debDir = "deb_build" - if os.path.isdir(debDir): - raise Exception('DEB build dir already exists: "%s"' % debDir) - sdist = "dist/pyqtgraph-%s.tar.gz" % version - if not os.path.isfile(sdist): - raise Exception("No source distribution; run `setup.py sdist` first.") - - # copy sdist to build directory and extract - os.mkdir(debDir) - renamedSdist = 'python-pyqtgraph_%s.orig.tar.gz' % version - shutil.copy(sdist, os.path.join(debDir, renamedSdist)) - if os.system("cd %s; tar -xzf %s" % (debDir, renamedSdist)) != 0: - raise Exception("Error extracting source distribution.") - buildDir = '%s/pyqtgraph-%s' % (debDir, version) - - # copy debian control structure - shutil.copytree('tools/debian', buildDir+'/debian') - - # Write changelog - #chlog = subprocess.check_output([sys.executable, 'tools/generateChangelog.py', 'CHANGELOG']) - #open('%s/pyqtgraph-%s/debian/changelog', 'w').write(chlog) - if os.system('python tools/generateChangelog.py CHANGELOG %s > %s/debian/changelog' % (version, buildDir)) != 0: - raise Exception("Error writing debian/changelog") - - # build package - if os.system('cd %s; debuild -us -uc' % buildDir) != 0: - raise Exception("Error during debuild.") - -class TestCommand(Command): - description = "" - user_options = [] - def initialize_options(self): - pass - def finalize_options(self): - pass - def run(self): - global cmd - cmd = self setup( version=version, - cmdclass={'build': Build, 'deb': DebCommand, 'test': TestCommand}, + cmdclass={'build': Build, 'deb': helpers.DebCommand, 'test': helpers.TestCommand}, packages=allPackages, package_dir={'pyqtgraph.examples': 'examples'}, ## install examples along with the rest of the source #package_data={'pyqtgraph': ['graphicsItems/PlotItem/*.png']}, diff --git a/tools/debian/control b/tools/debian/control index 5ea2d4f2..9d0519cc 100644 --- a/tools/debian/control +++ b/tools/debian/control @@ -2,7 +2,7 @@ Source: python-pyqtgraph Maintainer: Luke Campagnola Section: python Priority: optional -Standards-Version: 3.9.3 +Standards-Version: 3.9.4 Build-Depends: debhelper (>= 8) Package: python-pyqtgraph diff --git a/tools/generateChangelog.py b/tools/generateChangelog.py index 32c9ad2c..10601b35 100644 --- a/tools/generateChangelog.py +++ b/tools/generateChangelog.py @@ -1,70 +1,80 @@ import re, time, sys -if len(sys.argv) < 3: - sys.stderr.write("Must specify changelog file and latest release!\n") - sys.exit(-1) - -### Convert CHANGELOG format like: -""" -pyqtgraph-0.9.1 2012-12-29 - - - change - - change -""" - -### to debian changelog format: -""" -python-pyqtgraph (0.9.1-1) UNRELEASED; urgency=low - - * Initial release. - - -- Luke Sat, 29 Dec 2012 01:07:23 -0500 -""" +def generateDebianChangelog(package, logFile, version, maintainer): + """ + ------- Convert CHANGELOG format like: + pyqtgraph-0.9.1 2012-12-29 -releases = [] -current_version = None -current_log = None -current_date = None -for line in open(sys.argv[1]).readlines(): - match = re.match(r'pyqtgraph-(\d+\.\d+\.\d+(\.\d+)?)\s*(\d+-\d+-\d+)\s*$', line) - if match is None: - if current_log is not None: - current_log.append(line) - else: - if current_log is not None: - releases.append((current_version, current_log, current_date)) - current_version, current_date = match.groups()[0], match.groups()[2] - #sys.stderr.write("Found release %s\n" % current_version) - current_log = [] + - change + - change -if releases[0][0] != sys.argv[2]: - sys.stderr.write("Latest release in changelog (%s) does not match current release (%s)\n" % (releases[0][0], sys.argv[2])) - sys.exit(-1) -for release, changes, date in releases: - date = time.strptime(date, '%Y-%m-%d') - changeset = [ - "python-pyqtgraph (%s-1) UNRELEASED; urgency=low\n" % release, - "\n"] + changes + [ - " -- Luke %s -0%d00\n" % (time.strftime('%a, %d %b %Y %H:%M:%S', date), time.timezone/3600), - "\n" ] + -------- to debian changelog format: + python-pyqtgraph (0.9.1-1) UNRELEASED; urgency=low - # remove consecutive blank lines except between releases - clean = "" - lastBlank = True - for line in changeset: - if line.strip() == '': - if lastBlank: - continue + * Initial release. + + -- Luke Sat, 29 Dec 2012 01:07:23 -0500 + + + *package* is the name of the python package. + *logFile* is the CHANGELOG file to read; must have the format described above. + *version* will be used to check that the most recent log entry corresponds + to the current package version. + *maintainer* should be string like "Luke ". + """ + releases = [] + current_version = None + current_log = None + current_date = None + for line in open(logFile).readlines(): + match = re.match(package+r'-(\d+\.\d+\.\d+(\.\d+)?)\s*(\d+-\d+-\d+)\s*$', line) + if match is None: + if current_log is not None: + current_log.append(line) + else: + if current_log is not None: + releases.append((current_version, current_log, current_date)) + current_version, current_date = match.groups()[0], match.groups()[2] + #sys.stderr.write("Found release %s\n" % current_version) + current_log = [] + + if releases[0][0] != version: + raise Exception("Latest release in changelog (%s) does not match current release (%s)\n" % (releases[0][0], version)) + + output = [] + for release, changes, date in releases: + date = time.strptime(date, '%Y-%m-%d') + changeset = [ + "python-%s (%s-1) UNRELEASED; urgency=low\n" % (package, release), + "\n"] + changes + [ + " -- %s %s -0%d00\n" % (maintainer, time.strftime('%a, %d %b %Y %H:%M:%S', date), time.timezone/3600), + "\n" ] + + # remove consecutive blank lines except between releases + clean = "" + lastBlank = True + for line in changeset: + if line.strip() == '': + if lastBlank: + continue + else: + clean += line + lastBlank = True else: clean += line - lastBlank = True - else: - clean += line - lastBlank = False - - print clean - print "" + lastBlank = False + + output.append(clean) + output.append("") + return "\n".join(output) + "\n" +if __name__ == '__main__': + if len(sys.argv) < 5: + sys.stderr.write('Usage: generateChangelog.py package_name log_file version "Maintainer "\n') + sys.exit(-1) + + print generateDebianChangelog(*sys.argv[1:]) + diff --git a/tools/setupHelpers.py b/tools/setupHelpers.py index 216e6cc2..f1845ce4 100644 --- a/tools/setupHelpers.py +++ b/tools/setupHelpers.py @@ -111,4 +111,72 @@ def getVersionStrings(pkg): else: version = initVersion - return version, forcedVersion, gitVersion, initVersion \ No newline at end of file + return version, forcedVersion, gitVersion, initVersion + + + +from distutils.core import Command +import shutil, subprocess +from generateChangelog import generateDebianChangelog + +class DebCommand(Command): + description = "build .deb package using `debuild -us -uc`" + maintainer = "Luke " + debTemplate = "tools/debian" + debDir = "deb_build" + + user_options = [] + + def initialize_options(self): + self.cwd = None + + def finalize_options(self): + self.cwd = os.getcwd() + + def run(self): + version = self.distribution.get_version() + pkgName = self.distribution.get_name() + debName = "python-" + pkgName + debDir = self.debDir + + assert os.getcwd() == self.cwd, 'Must be in package root: %s' % self.cwd + + if os.path.isdir(debDir): + raise Exception('DEB build dir already exists: "%s"' % debDir) + sdist = "dist/%s-%s.tar.gz" % (pkgName, version) + if not os.path.isfile(sdist): + raise Exception("No source distribution; run `setup.py sdist` first.") + + # copy sdist to build directory and extract + os.mkdir(debDir) + renamedSdist = '%s_%s.orig.tar.gz' % (debName, version) + shutil.copy(sdist, os.path.join(debDir, renamedSdist)) + if os.system("cd %s; tar -xzf %s" % (debDir, renamedSdist)) != 0: + raise Exception("Error extracting source distribution.") + buildDir = '%s/%s-%s' % (debDir, pkgName, version) + + # copy debian control structure + shutil.copytree(self.debTemplate, buildDir+'/debian') + + # Write new changelog + chlog = generateDebianChangelog(pkgName, 'CHANGELOG', version, self.maintainer) + open(buildDir+'/debian/changelog', 'w').write(chlog) + + # build package + if os.system('cd %s; debuild -us -uc' % buildDir) != 0: + raise Exception("Error during debuild.") + + +class TestCommand(Command): + description = "" + user_options = [] + def initialize_options(self): + pass + def finalize_options(self): + pass + def run(self): + global cmd + cmd = self + print self.distribution.name + print self.distribution.version + \ No newline at end of file From c8739e54257877eaa9b7a997540837ab90d93a7e Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Sun, 12 Jan 2014 23:59:53 -0500 Subject: [PATCH 3/5] Updated build system to use pybuild - now generates python-pyqtgraph, python3-pyqtgraph, and python-pyqtgraph-doc packages - `python setup.py sdist deb` works --- MANIFEST.in | 1 + tools/debian/changelog | 5 ---- tools/debian/control | 39 +++++++++++++++++++++++--- tools/debian/files | 1 - tools/debian/postrm | 3 -- tools/debian/python-pyqtgraph.install | 1 + tools/debian/python3-pyqtgraph.install | 1 + tools/debian/rules | 13 ++++++++- tools/debian/watch | 3 ++ tools/generateChangelog.py | 2 +- tools/setupHelpers.py | 14 +++++---- 11 files changed, 63 insertions(+), 20 deletions(-) delete mode 100644 tools/debian/changelog delete mode 100644 tools/debian/files delete mode 100755 tools/debian/postrm create mode 100644 tools/debian/python-pyqtgraph.install create mode 100644 tools/debian/python3-pyqtgraph.install create mode 100644 tools/debian/watch diff --git a/MANIFEST.in b/MANIFEST.in index f4158fac..c6667d04 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -5,4 +5,5 @@ recursive-include doc *.rst *.py *.svg *.png *.jpg recursive-include doc/build/html * recursive-include tools * include doc/Makefile doc/make.bat README.md LICENSE.txt CHANGELOG +global-exclude *.pyc diff --git a/tools/debian/changelog b/tools/debian/changelog deleted file mode 100644 index 1edf45f3..00000000 --- a/tools/debian/changelog +++ /dev/null @@ -1,5 +0,0 @@ -python-pyqtgraph (0.9.1-1) UNRELEASED; urgency=low - - * Initial release. - - -- Luke Sat, 29 Dec 2012 01:07:23 -0500 diff --git a/tools/debian/control b/tools/debian/control index 9d0519cc..a516920d 100644 --- a/tools/debian/control +++ b/tools/debian/control @@ -3,16 +3,47 @@ Maintainer: Luke Campagnola Section: python Priority: optional Standards-Version: 3.9.4 -Build-Depends: debhelper (>= 8) +Build-Depends: debhelper (>= 8), python-all (>= 2.6.6-3~), python-setuptools, python3-all, python3-setuptools, python-docutils, python-sphinx (>= 1.0.7+dfsg-1~) +X-Python-Version: >= 2.6 +X-Python3-Version: >= 3.2 Package: python-pyqtgraph Architecture: all Homepage: http://www.pyqtgraph.org -Depends: python (>= 2.6), python-support (>= 0.90), python-qt4 | python-pyside, python-scipy, python-numpy, ${misc:Depends} -Suggests: python-opengl, python-qt4-gl -Description: Scientific Graphics and GUI Library for Python +Depends: python-qt4 | python-pyside, python-scipy, python-numpy, ${python:Depends}, ${misc:Depends} +Suggests: python-pyqtgraph-doc, python-opengl, python-qt4-gl +Description: Scientific Graphics and GUI Library (Python 2) PyQtGraph is a pure-python graphics and GUI library built on PyQt4 and numpy. It is intended for use in mathematics / scientific / engineering applications. Despite being written entirely in python, the library is very fast due to its heavy leverage of numpy for number crunching and Qt's GraphicsView framework for fast display. + . + This is the Python 2 version of the package. + +Package: python3-pyqtgraph +Architecture: all +Homepage: http://www.pyqtgraph.org +Depends: python-qt4 | python-pyside, python-scipy, python-numpy, ${python3:Depends}, ${misc:Depends} +Suggests: python-pyqtgraph-doc, python-opengl, python-qt4-gl +Description: Scientific Graphics and GUI Library (Python 3) + PyQtGraph is a pure-python graphics and GUI library built on PyQt4 and numpy. + It is intended for use in mathematics / scientific / engineering applications. + Despite being written entirely in python, the library is very fast due to its + heavy leverage of numpy for number crunching and Qt's GraphicsView framework + for fast display. + . + This is the Python 3 version of the package. + +Package: python-pyqtgraph-doc +Architecture: all +Section: doc +Depends: ${sphinxdoc:Depends}, ${misc:Depends} +Description: Scientific Graphics and GUI Library (common documentation) + PyQtGraph is a pure-python graphics and GUI library built on PyQt4 and numpy. + It is intended for use in mathematics / scientific / engineering applications. + Despite being written entirely in python, the library is very fast due to its + heavy leverage of numpy for number crunching and Qt's GraphicsView framework + for fast display. + . + This is the common documentation package. diff --git a/tools/debian/files b/tools/debian/files deleted file mode 100644 index 4af05533..00000000 --- a/tools/debian/files +++ /dev/null @@ -1 +0,0 @@ -python-pyqtgraph_0.9.1-1_all.deb python optional diff --git a/tools/debian/postrm b/tools/debian/postrm deleted file mode 100755 index e1eae9f2..00000000 --- a/tools/debian/postrm +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -e -#DEBHELPER# -rm -rf /usr/lib/python2.7/dist-packages/pyqtgraph diff --git a/tools/debian/python-pyqtgraph.install b/tools/debian/python-pyqtgraph.install new file mode 100644 index 00000000..b2cc1360 --- /dev/null +++ b/tools/debian/python-pyqtgraph.install @@ -0,0 +1 @@ +usr/lib/python2* diff --git a/tools/debian/python3-pyqtgraph.install b/tools/debian/python3-pyqtgraph.install new file mode 100644 index 00000000..4606faae --- /dev/null +++ b/tools/debian/python3-pyqtgraph.install @@ -0,0 +1 @@ +usr/lib/python3* diff --git a/tools/debian/rules b/tools/debian/rules index 2d33f6ac..3132fbfd 100755 --- a/tools/debian/rules +++ b/tools/debian/rules @@ -1,4 +1,15 @@ #!/usr/bin/make -f +#export DH_VERBOSE=1 +export PYBUILD_NAME=pyqtgraph %: - dh $@ + dh $@ --with python2,python3,sphinxdoc --buildsystem=pybuild + +override_dh_installdocs: + PYTHONPATH=`pwd` make -C doc html + dh_installdocs -ppython-pyqtgraph-doc doc/build/html + dh_installdocs -A + +override_dh_clean: + dh_clean + find ./ -name "*.pyc" -delete \ No newline at end of file diff --git a/tools/debian/watch b/tools/debian/watch new file mode 100644 index 00000000..85ff1a55 --- /dev/null +++ b/tools/debian/watch @@ -0,0 +1,3 @@ +version=3 +opts=uversionmangle=s/(rc|dev|a|b|c)/~$1/ \ +https://pypi.python.org/packages/source/p/pyqtgraph/pyqtgraph-(.*)\.(?:tar\.gz|zip|tar\.bz2) diff --git a/tools/generateChangelog.py b/tools/generateChangelog.py index 10601b35..3dcd692d 100644 --- a/tools/generateChangelog.py +++ b/tools/generateChangelog.py @@ -76,5 +76,5 @@ if __name__ == '__main__': sys.stderr.write('Usage: generateChangelog.py package_name log_file version "Maintainer "\n') sys.exit(-1) - print generateDebianChangelog(*sys.argv[1:]) + print(generateDebianChangelog(*sys.argv[1:])) diff --git a/tools/setupHelpers.py b/tools/setupHelpers.py index f1845ce4..5b17069a 100644 --- a/tools/setupHelpers.py +++ b/tools/setupHelpers.py @@ -114,14 +114,13 @@ def getVersionStrings(pkg): return version, forcedVersion, gitVersion, initVersion - from distutils.core import Command import shutil, subprocess from generateChangelog import generateDebianChangelog class DebCommand(Command): description = "build .deb package using `debuild -us -uc`" - maintainer = "Luke " + maintainer = "Luke Campagnola " debTemplate = "tools/debian" debDir = "deb_build" @@ -150,24 +149,30 @@ class DebCommand(Command): # copy sdist to build directory and extract os.mkdir(debDir) renamedSdist = '%s_%s.orig.tar.gz' % (debName, version) + print("copy %s => %s" % (sdist, os.path.join(debDir, renamedSdist))) shutil.copy(sdist, os.path.join(debDir, renamedSdist)) + print("cd %s; tar -xzf %s" % (debDir, renamedSdist)) if os.system("cd %s; tar -xzf %s" % (debDir, renamedSdist)) != 0: raise Exception("Error extracting source distribution.") buildDir = '%s/%s-%s' % (debDir, pkgName, version) # copy debian control structure + print("copytree %s => %s" % (self.debTemplate, buildDir+'/debian')) shutil.copytree(self.debTemplate, buildDir+'/debian') # Write new changelog chlog = generateDebianChangelog(pkgName, 'CHANGELOG', version, self.maintainer) + print("write changelog %s" % buildDir+'/debian/changelog') open(buildDir+'/debian/changelog', 'w').write(chlog) # build package + print('cd %s; debuild -us -uc' % buildDir) if os.system('cd %s; debuild -us -uc' % buildDir) != 0: raise Exception("Error during debuild.") class TestCommand(Command): + """Just for learning about distutils; not for running package tests.""" description = "" user_options = [] def initialize_options(self): @@ -177,6 +182,5 @@ class TestCommand(Command): def run(self): global cmd cmd = self - print self.distribution.name - print self.distribution.version - \ No newline at end of file + print(self.distribution.name) + print(self.distribution.version) From 2f1cb26549d70b713155427f4d43ae0a59e5e311 Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Sun, 19 Jan 2014 21:14:49 -0500 Subject: [PATCH 4/5] remove tools/debian; will add a new branch with debian/ at the root. --- tools/debian/compat | 1 - tools/debian/control | 49 -------------------------- tools/debian/copyright | 10 ------ tools/debian/python-pyqtgraph.install | 1 - tools/debian/python3-pyqtgraph.install | 1 - tools/debian/rules | 15 -------- tools/debian/source/format | 1 - tools/debian/watch | 3 -- 8 files changed, 81 deletions(-) delete mode 100644 tools/debian/compat delete mode 100644 tools/debian/control delete mode 100644 tools/debian/copyright delete mode 100644 tools/debian/python-pyqtgraph.install delete mode 100644 tools/debian/python3-pyqtgraph.install delete mode 100755 tools/debian/rules delete mode 100644 tools/debian/source/format delete mode 100644 tools/debian/watch diff --git a/tools/debian/compat b/tools/debian/compat deleted file mode 100644 index 45a4fb75..00000000 --- a/tools/debian/compat +++ /dev/null @@ -1 +0,0 @@ -8 diff --git a/tools/debian/control b/tools/debian/control deleted file mode 100644 index a516920d..00000000 --- a/tools/debian/control +++ /dev/null @@ -1,49 +0,0 @@ -Source: python-pyqtgraph -Maintainer: Luke Campagnola -Section: python -Priority: optional -Standards-Version: 3.9.4 -Build-Depends: debhelper (>= 8), python-all (>= 2.6.6-3~), python-setuptools, python3-all, python3-setuptools, python-docutils, python-sphinx (>= 1.0.7+dfsg-1~) -X-Python-Version: >= 2.6 -X-Python3-Version: >= 3.2 - -Package: python-pyqtgraph -Architecture: all -Homepage: http://www.pyqtgraph.org -Depends: python-qt4 | python-pyside, python-scipy, python-numpy, ${python:Depends}, ${misc:Depends} -Suggests: python-pyqtgraph-doc, python-opengl, python-qt4-gl -Description: Scientific Graphics and GUI Library (Python 2) - PyQtGraph is a pure-python graphics and GUI library built on PyQt4 and numpy. - It is intended for use in mathematics / scientific / engineering applications. - Despite being written entirely in python, the library is very fast due to its - heavy leverage of numpy for number crunching and Qt's GraphicsView framework - for fast display. - . - This is the Python 2 version of the package. - -Package: python3-pyqtgraph -Architecture: all -Homepage: http://www.pyqtgraph.org -Depends: python-qt4 | python-pyside, python-scipy, python-numpy, ${python3:Depends}, ${misc:Depends} -Suggests: python-pyqtgraph-doc, python-opengl, python-qt4-gl -Description: Scientific Graphics and GUI Library (Python 3) - PyQtGraph is a pure-python graphics and GUI library built on PyQt4 and numpy. - It is intended for use in mathematics / scientific / engineering applications. - Despite being written entirely in python, the library is very fast due to its - heavy leverage of numpy for number crunching and Qt's GraphicsView framework - for fast display. - . - This is the Python 3 version of the package. - -Package: python-pyqtgraph-doc -Architecture: all -Section: doc -Depends: ${sphinxdoc:Depends}, ${misc:Depends} -Description: Scientific Graphics and GUI Library (common documentation) - PyQtGraph is a pure-python graphics and GUI library built on PyQt4 and numpy. - It is intended for use in mathematics / scientific / engineering applications. - Despite being written entirely in python, the library is very fast due to its - heavy leverage of numpy for number crunching and Qt's GraphicsView framework - for fast display. - . - This is the common documentation package. diff --git a/tools/debian/copyright b/tools/debian/copyright deleted file mode 100644 index 22791ae3..00000000 --- a/tools/debian/copyright +++ /dev/null @@ -1,10 +0,0 @@ -Copyright (c) 2012 University of North Carolina at Chapel Hill -Luke Campagnola ('luke.campagnola@%s.com' % 'gmail') - -The MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/tools/debian/python-pyqtgraph.install b/tools/debian/python-pyqtgraph.install deleted file mode 100644 index b2cc1360..00000000 --- a/tools/debian/python-pyqtgraph.install +++ /dev/null @@ -1 +0,0 @@ -usr/lib/python2* diff --git a/tools/debian/python3-pyqtgraph.install b/tools/debian/python3-pyqtgraph.install deleted file mode 100644 index 4606faae..00000000 --- a/tools/debian/python3-pyqtgraph.install +++ /dev/null @@ -1 +0,0 @@ -usr/lib/python3* diff --git a/tools/debian/rules b/tools/debian/rules deleted file mode 100755 index 3132fbfd..00000000 --- a/tools/debian/rules +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/make -f -#export DH_VERBOSE=1 -export PYBUILD_NAME=pyqtgraph - -%: - dh $@ --with python2,python3,sphinxdoc --buildsystem=pybuild - -override_dh_installdocs: - PYTHONPATH=`pwd` make -C doc html - dh_installdocs -ppython-pyqtgraph-doc doc/build/html - dh_installdocs -A - -override_dh_clean: - dh_clean - find ./ -name "*.pyc" -delete \ No newline at end of file diff --git a/tools/debian/source/format b/tools/debian/source/format deleted file mode 100644 index 163aaf8d..00000000 --- a/tools/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/tools/debian/watch b/tools/debian/watch deleted file mode 100644 index 85ff1a55..00000000 --- a/tools/debian/watch +++ /dev/null @@ -1,3 +0,0 @@ -version=3 -opts=uversionmangle=s/(rc|dev|a|b|c)/~$1/ \ -https://pypi.python.org/packages/source/p/pyqtgraph/pyqtgraph-(.*)\.(?:tar\.gz|zip|tar\.bz2) From d81998461fbe4540daa2fd1025d61553ab7d25d7 Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Wed, 22 Jan 2014 14:23:10 -0500 Subject: [PATCH 5/5] copy setHelpers.py changes from debian/ branch --- tools/setupHelpers.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tools/setupHelpers.py b/tools/setupHelpers.py index 5b17069a..9e6be1d5 100644 --- a/tools/setupHelpers.py +++ b/tools/setupHelpers.py @@ -49,7 +49,7 @@ def getGitVersion(tagPrefix): lastTag = gitCommit(lastTagName) head = gitCommit('HEAD') if head != lastTag: - branch = re.search(r'\* (.*)', check_output(['git', 'branch'], universal_newlines=True)).group(1) + branch = getGitBranch() gitVersion = gitVersion + "-%s-%s" % (branch, head[:10]) # any uncommitted modifications? @@ -65,6 +65,13 @@ def getGitVersion(tagPrefix): return gitVersion +def getGitBranch(): + m = re.search(r'\* (.*)', check_output(['git', 'branch'], universal_newlines=True)) + if m is None: + return '' + else: + return m.group(1) + def getVersionStrings(pkg): """ Returns 4 version strings: @@ -102,10 +109,11 @@ def getVersionStrings(pkg): forcedVersion = sys.argv[i].replace('--force-version=', '') sys.argv.pop(i) + ## Finally decide on a version string to use: if forcedVersion is not None: version = forcedVersion - elif gitVersion is not None: + elif gitVersion is not None and getGitBranch() != 'debian': # ignore git version if this is debian branch version = gitVersion sys.stderr.write("Detected git commit; will use version string: '%s'\n" % version) else: @@ -121,7 +129,7 @@ from generateChangelog import generateDebianChangelog class DebCommand(Command): description = "build .deb package using `debuild -us -uc`" maintainer = "Luke Campagnola " - debTemplate = "tools/debian" + debTemplate = "debian" debDir = "deb_build" user_options = []