316 lines
11 KiB
Python
316 lines
11 KiB
Python
import sys
|
|
|
|
sys.path.insert(0, sys.argv[1])
|
|
import py
|
|
|
|
toolpath = py.path.local(__file__)
|
|
binpath = py.path.local(py.__file__).dirpath('bin')
|
|
|
|
def error(msg):
|
|
print >>sys.stderr, msg
|
|
raise SystemExit, 1
|
|
|
|
def reformat(text):
|
|
return " ".join(text.split())
|
|
|
|
class SetupWriter(object):
|
|
EXCLUDES = ("MANIFEST.in", "contrib")
|
|
|
|
def __init__(self, basedir, pkg, setuptools=False):
|
|
self.basedir = basedir
|
|
self.setuptools = setuptools
|
|
assert self.basedir.check()
|
|
self.pkg = pkg
|
|
self.meta = pkg.__pkg__
|
|
self.lines = []
|
|
self.allpaths = self.getallpath(self.basedir)
|
|
|
|
def getallpath(self, basedir):
|
|
contrib = self.basedir.join("contrib")
|
|
allpath = []
|
|
lines = py.process.cmdexec("hg st -mcan").split("\n")
|
|
for path in lines:
|
|
p = basedir.join(path)
|
|
assert p.check(), p
|
|
if not p.relto(contrib) and p != contrib and not self.isexcluded(p):
|
|
allpath.append(p)
|
|
return allpath
|
|
|
|
def append(self, string):
|
|
lines = string.split("\n")
|
|
while lines:
|
|
if not lines[0].strip():
|
|
lines.pop(0)
|
|
continue
|
|
break
|
|
if not lines:
|
|
self.lines.append("")
|
|
return
|
|
line = lines[0]
|
|
indent = len(line) - len(line.lstrip())
|
|
for line in lines:
|
|
if line.strip():
|
|
assert not line[:indent].strip(), line
|
|
line = line[indent:]
|
|
self.lines.append(line)
|
|
|
|
def write_winfuncs(self):
|
|
self.append('''
|
|
''')
|
|
|
|
def tip_info(self, indent=8):
|
|
old = self.basedir.chdir()
|
|
indent = " " * indent
|
|
try:
|
|
info = []
|
|
output = py.process.cmdexec(
|
|
"hg tip --template '" # tags: {tags}\n"
|
|
#"branch: {branches}\n"
|
|
"revision: {rev}:{node}\n'"
|
|
)
|
|
for line in output.split("\n"):
|
|
info.append("%s %s" %(indent, line.strip()))
|
|
return "\n".join(info)
|
|
finally:
|
|
old.chdir()
|
|
|
|
def setup_header(self):
|
|
#tooltime = "%s %s" %(py.std.time.asctime(), py.std.time.tzname[0])
|
|
toolname = toolpath.basename
|
|
#toolrevision = py.path.svnwc(toolpath).info().rev
|
|
|
|
pkgname = self.pkg.__name__
|
|
self.append('"""py lib / py.test setup.py file"""')
|
|
self.append('import os, sys')
|
|
self.append("from setuptools import setup")
|
|
|
|
def setup_trailer(self):
|
|
self.append('''
|
|
if __name__ == '__main__':
|
|
main()
|
|
''')
|
|
|
|
def setup_function(self):
|
|
params = self.__dict__.copy()
|
|
params.update(self.meta.__dict__)
|
|
self.append('long_description = """')
|
|
for line in params['long_description'].split('\n'):
|
|
self.append(line)
|
|
self.append('"""')
|
|
trunk = None
|
|
if params['version'] == 'trunk':
|
|
trunk = 'trunk'
|
|
self.append('trunk = %r' % trunk)
|
|
self.append('''
|
|
def main():
|
|
setup(
|
|
name=%(name)r,
|
|
description=%(description)r,
|
|
long_description = long_description,
|
|
version= trunk or %(version)r,
|
|
url=%(url)r,
|
|
license=%(license)r,
|
|
platforms=%(platforms)r,
|
|
author=%(author)r,
|
|
author_email=%(author_email)r,
|
|
''' % params)
|
|
indent = " " * 8
|
|
self.append_pprint(indent, entry_points={'console_scripts':self.getconsolescripts()})
|
|
self.append_pprint(indent, classifiers=self.meta.classifiers)
|
|
self.append_pprint(indent, packages=self.getpackages())
|
|
self.append_pprint(indent, package_data=self.getpackagedata())
|
|
self.append_pprint(indent, zip_safe=True)
|
|
self.append_pprint(indent, install_requires=['apipkg'])
|
|
self.lines.append(indent[4:] + ")\n")
|
|
|
|
def setup_scripts(self):
|
|
# XXX this was used for a different approach
|
|
not used
|
|
self.append("""
|
|
def getscripts():
|
|
if sys.platform == "win32":
|
|
base = "py/bin/win32/"
|
|
ext = ".cmd"
|
|
else:
|
|
base = "py/bin/"
|
|
ext = ""
|
|
l = []
|
|
for name in %r:
|
|
l.append(base + name + ext)
|
|
return l
|
|
""" % ([script.basename for script in binpath.listdir("py.*")]))
|
|
|
|
def append_pprint(self, indent, append=",", **kw):
|
|
for name, value in kw.items():
|
|
stringio = py.std.StringIO.StringIO()
|
|
value = py.std.pprint.pprint(value, stream=stringio)
|
|
stringio.seek(0)
|
|
lines = stringio.readlines()
|
|
line = lines.pop(0).rstrip()
|
|
self.lines.append(indent + "%s=%s" %(name, line))
|
|
indent = indent + " " * (len(name)+1)
|
|
for line in lines:
|
|
self.lines.append(indent + line.rstrip())
|
|
self.lines[-1] = self.lines[-1] + append
|
|
|
|
def getconsolescripts(self):
|
|
bindir = self.basedir.join('py', 'bin')
|
|
scripts = []
|
|
for p in self.allpaths:
|
|
if p.dirpath() == bindir:
|
|
if p.basename.startswith('py.'):
|
|
shortname = "py" + p.basename[3:]
|
|
scripts.append("%s = py.cmdline:%s" %
|
|
(p.basename, shortname))
|
|
return scripts
|
|
|
|
def getscripts(self):
|
|
bindir = self.basedir.join('py', 'bin')
|
|
scripts = []
|
|
for p in self.allpaths:
|
|
if p.dirpath() == bindir:
|
|
if p.basename.startswith('py.'):
|
|
scripts.append(p.relto(self.basedir))
|
|
return scripts
|
|
|
|
def getpackages(self):
|
|
packages = []
|
|
for p in self.allpaths: # contains no directories!
|
|
#if p.basename == "py":
|
|
# continue
|
|
if p.dirpath('__init__.py').check():
|
|
modpath = p.dirpath().relto(self.basedir).replace(p.sep, '.')
|
|
if modpath != "py" and not modpath.startswith("py."):
|
|
continue
|
|
if modpath in packages:
|
|
continue
|
|
for exclude in self.EXCLUDES:
|
|
if modpath.startswith(exclude):
|
|
print "EXCLUDING", modpath
|
|
break
|
|
else:
|
|
packages.append(modpath)
|
|
packages.sort()
|
|
return packages
|
|
|
|
def getpackagedata(self):
|
|
datafiles = []
|
|
pkgbase = self.basedir.join(self.pkg.__name__)
|
|
for p in self.allpaths:
|
|
if p.check(file=1) and (not p.dirpath("__init__.py").check()
|
|
or p.ext != ".py"):
|
|
if p.dirpath() != self.basedir:
|
|
x = p.relto(pkgbase)
|
|
if x:
|
|
datafiles.append(p.relto(pkgbase))
|
|
return {'py': datafiles}
|
|
|
|
def getdatafiles(self):
|
|
datafiles = []
|
|
for p in self.allpaths:
|
|
if p.check(file=1) and not p.ext == ".py":
|
|
if p.dirpath() != self.basedir:
|
|
datafiles.append(p.relto(self.basedir))
|
|
return datafiles
|
|
|
|
def setup_win32(self):
|
|
import winpath
|
|
self.append(py.std.inspect.getsource(winpath))
|
|
self.append("""
|
|
from distutils.command.install import install
|
|
class my_install(install):
|
|
def finalize_other(self):
|
|
install.finalize_other(self)
|
|
on_win32_add_to_PATH()
|
|
cmdclass = {'install': my_install}
|
|
""")
|
|
|
|
def setup_win32(self):
|
|
self.append(r'''
|
|
# scripts for windows: turn "py.SCRIPT" into "py_SCRIPT" and create
|
|
# "py.SCRIPT.cmd" files invoking "py_SCRIPT"
|
|
from distutils.command.install_scripts import install_scripts
|
|
class my_install_scripts(install_scripts):
|
|
def run(self):
|
|
install_scripts.run(self)
|
|
#print self.outfiles
|
|
for fn in self.outfiles:
|
|
basename = os.path.basename(fn)
|
|
if basename.startswith("py.") and not basename.endswith(".cmd"):
|
|
newbasename = basename.replace(".", "_")
|
|
newfn = os.path.join(os.path.dirname(fn), newbasename)
|
|
if os.path.exists(newfn):
|
|
os.remove(newfn)
|
|
os.rename(fn, newfn)
|
|
fncmd = fn + ".cmd"
|
|
if os.path.exists(fncmd):
|
|
os.remove(fncmd)
|
|
f = open(fncmd, 'w')
|
|
f.write("@echo off\n")
|
|
f.write('python "%%~dp0\%s" %%*' %(newbasename))
|
|
f.close()
|
|
if sys.platform == "win32":
|
|
cmdclass = {'install_scripts': my_install_scripts}
|
|
else:
|
|
cmdclass = {}
|
|
''')
|
|
|
|
def write_setup(self):
|
|
self.setup_header()
|
|
self.setup_function()
|
|
#self.setup_scripts()
|
|
#self.setup_win32()
|
|
self.setup_trailer()
|
|
targetfile = self.basedir.join("setup.py")
|
|
targetfile.write("\n".join(self.lines))
|
|
print "wrote", targetfile
|
|
|
|
def isexcluded(self, wcpath):
|
|
return wcpath.basename[0] == "."
|
|
rel = wcpath.relto(self.basedir)
|
|
if rel.find("testing") != -1:
|
|
return True
|
|
|
|
def write_manifest(self):
|
|
lines = []
|
|
for p in self.allpaths:
|
|
if p.check(dir=1):
|
|
continue
|
|
toadd = p.relto(self.basedir)
|
|
if toadd:
|
|
for exclude in self.EXCLUDES:
|
|
if toadd.startswith(exclude):
|
|
break
|
|
assert toadd.find(exclude) == -1, (toadd, exclude)
|
|
else:
|
|
lines.append("%s" %(toadd))
|
|
lines.sort()
|
|
targetfile = self.basedir.join("MANIFEST")
|
|
targetfile.write("\n".join(lines))
|
|
print "wrote", targetfile
|
|
|
|
def write_all(self):
|
|
#self.write_manifest()
|
|
self.write_setup()
|
|
|
|
def parseargs():
|
|
basedir = py.path.local(sys.argv[1])
|
|
if not basedir.check():
|
|
error("basedir not found: %s" %(basedir,))
|
|
pydir = basedir.join('py')
|
|
if not pydir.check():
|
|
error("no 'py' directory found in: %s" %(pydir,))
|
|
actualpydir = py.path.local(py.__file__).dirpath()
|
|
if pydir != actualpydir:
|
|
error("package dir conflict, %s != %s" %(pydir, actualpydir))
|
|
return basedir
|
|
|
|
def main(basedir=None):
|
|
if basedir is None:
|
|
basedir = parseargs()
|
|
writer = SetupWriter(basedir, py, setuptools=True)
|
|
writer.write_all()
|
|
|
|
if __name__ == "__main__":
|
|
main()
|