2014-01-12 15:35:31 +00:00
|
|
|
import os, sys, re
|
2014-01-23 18:25:00 +00:00
|
|
|
try:
|
|
|
|
from subprocess import check_output
|
|
|
|
except ImportError:
|
|
|
|
import subprocess as sp
|
|
|
|
def check_output(*args, **kwds):
|
|
|
|
kwds['stdout'] = sp.PIPE
|
|
|
|
proc = sp.Popen(*args, **kwds)
|
|
|
|
output = proc.stdout.read()
|
|
|
|
proc.wait()
|
|
|
|
if proc.returncode != 0:
|
2014-03-25 00:48:02 +00:00
|
|
|
ex = Exception("Process had nonzero return value %d" % proc.returncode)
|
|
|
|
ex.returncode = proc.returncode
|
|
|
|
ex.output = output
|
|
|
|
raise ex
|
2014-01-23 18:25:00 +00:00
|
|
|
return output
|
2014-01-12 15:35:31 +00:00
|
|
|
|
2014-03-25 00:48:02 +00:00
|
|
|
FLAKE_TESTS = ("E101,E111,E112,E113,E122,E125,E133,E223,E224,"
|
|
|
|
"E242,E273,E274,E304,E502,E703,E901,E902,"
|
|
|
|
"W191,W601,W602,W603,W604")
|
|
|
|
|
|
|
|
def checkStyle():
|
|
|
|
try:
|
|
|
|
out = check_output(['flake8', '--select=%s' % FLAKE_TESTS, '--statistics', 'pyqtgraph/'])
|
|
|
|
ret = 0
|
|
|
|
print("All style checks OK.")
|
|
|
|
except Exception as e:
|
|
|
|
out = e.output
|
|
|
|
ret = e.returncode
|
2014-03-25 01:48:43 +00:00
|
|
|
print(out.decode('utf-8'))
|
2014-03-25 00:48:02 +00:00
|
|
|
return ret
|
|
|
|
|
|
|
|
def unitTests():
|
|
|
|
try:
|
2014-03-25 03:30:19 +00:00
|
|
|
if sys.version[0] == '3':
|
2014-03-25 02:31:56 +00:00
|
|
|
out = check_output('PYTHONPATH=. py.test-3', shell=True)
|
|
|
|
else:
|
|
|
|
out = check_output('PYTHONPATH=. py.test', shell=True)
|
2014-03-25 00:48:02 +00:00
|
|
|
ret = 0
|
|
|
|
except Exception as e:
|
|
|
|
out = e.output
|
|
|
|
ret = e.returncode
|
2014-03-25 01:48:43 +00:00
|
|
|
print(out.decode('utf-8'))
|
2014-03-25 00:48:02 +00:00
|
|
|
return ret
|
|
|
|
|
2014-01-12 15:35:31 +00:00
|
|
|
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:
|
2014-01-22 19:23:10 +00:00
|
|
|
branch = getGitBranch()
|
2014-01-12 15:35:31 +00:00
|
|
|
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
|
|
|
|
|
2014-01-22 19:23:10 +00:00
|
|
|
def getGitBranch():
|
|
|
|
m = re.search(r'\* (.*)', check_output(['git', 'branch'], universal_newlines=True))
|
|
|
|
if m is None:
|
|
|
|
return ''
|
|
|
|
else:
|
|
|
|
return m.group(1)
|
|
|
|
|
2014-01-12 15:35:31 +00:00
|
|
|
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)
|
|
|
|
|
2014-01-22 19:23:10 +00:00
|
|
|
|
2014-01-12 15:35:31 +00:00
|
|
|
## Finally decide on a version string to use:
|
|
|
|
if forcedVersion is not None:
|
|
|
|
version = forcedVersion
|
2014-01-22 19:23:10 +00:00
|
|
|
elif gitVersion is not None and getGitBranch() != 'debian': # ignore git version if this is debian branch
|
2014-01-12 15:35:31 +00:00
|
|
|
version = gitVersion
|
|
|
|
sys.stderr.write("Detected git commit; will use version string: '%s'\n" % version)
|
|
|
|
else:
|
|
|
|
version = initVersion
|
|
|
|
|
2014-01-12 16:50:52 +00:00
|
|
|
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`"
|
2014-01-13 04:59:53 +00:00
|
|
|
maintainer = "Luke Campagnola <luke.campagnola@gmail.com>"
|
2014-01-22 19:23:10 +00:00
|
|
|
debTemplate = "debian"
|
2014-01-12 16:50:52 +00:00
|
|
|
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)
|
2014-01-13 04:59:53 +00:00
|
|
|
print("copy %s => %s" % (sdist, os.path.join(debDir, renamedSdist)))
|
2014-01-12 16:50:52 +00:00
|
|
|
shutil.copy(sdist, os.path.join(debDir, renamedSdist))
|
2014-01-13 04:59:53 +00:00
|
|
|
print("cd %s; tar -xzf %s" % (debDir, renamedSdist))
|
2014-01-12 16:50:52 +00:00
|
|
|
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
|
2014-01-13 04:59:53 +00:00
|
|
|
print("copytree %s => %s" % (self.debTemplate, buildDir+'/debian'))
|
2014-01-12 16:50:52 +00:00
|
|
|
shutil.copytree(self.debTemplate, buildDir+'/debian')
|
|
|
|
|
|
|
|
# Write new changelog
|
|
|
|
chlog = generateDebianChangelog(pkgName, 'CHANGELOG', version, self.maintainer)
|
2014-01-13 04:59:53 +00:00
|
|
|
print("write changelog %s" % buildDir+'/debian/changelog')
|
2014-01-12 16:50:52 +00:00
|
|
|
open(buildDir+'/debian/changelog', 'w').write(chlog)
|
|
|
|
|
|
|
|
# build package
|
2014-01-13 04:59:53 +00:00
|
|
|
print('cd %s; debuild -us -uc' % buildDir)
|
2014-01-12 16:50:52 +00:00
|
|
|
if os.system('cd %s; debuild -us -uc' % buildDir) != 0:
|
|
|
|
raise Exception("Error during debuild.")
|
|
|
|
|
|
|
|
|
2014-03-25 00:48:02 +00:00
|
|
|
class DebugCommand(Command):
|
|
|
|
"""Just for learning about distutils."""
|
2014-01-12 16:50:52 +00:00
|
|
|
description = ""
|
|
|
|
user_options = []
|
|
|
|
def initialize_options(self):
|
|
|
|
pass
|
|
|
|
def finalize_options(self):
|
|
|
|
pass
|
|
|
|
def run(self):
|
|
|
|
global cmd
|
|
|
|
cmd = self
|
2014-01-13 04:59:53 +00:00
|
|
|
print(self.distribution.name)
|
|
|
|
print(self.distribution.version)
|
2014-03-25 00:48:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
class TestCommand(Command):
|
|
|
|
description = "Run all package tests and exit immediately with informative return code."
|
|
|
|
user_options = []
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
sys.exit(unitTests())
|
|
|
|
|
|
|
|
|
|
|
|
def initialize_options(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def finalize_options(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class StyleCommand(Command):
|
|
|
|
description = "Check all code for style, exit immediately with informative return code."
|
|
|
|
user_options = []
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
sys.exit(checkStyle())
|
|
|
|
|
|
|
|
def initialize_options(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def finalize_options(self):
|
|
|
|
pass
|
|
|
|
|