test_ok2/bin-for-dist/gensetup.py

343 lines
12 KiB
Python

import sys
sys.path.insert(0, sys.argv[1])
import py
toolpath = py.magic.autopath()
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__
info = self.tip_info()
self.append('''
"""
py lib / py.test setup.py file, autogenerated by %(toolname)s
''' % locals())
#self.append(info)
self.append('''
"""
import os, sys
''')
if self.setuptools:
#import ez_setup
#ez_setup.use_setuptools()
self.append("""
from setuptools import setup
""")
else:
self.append("""
from distutils.core 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__)
#params['url'] = self.wcinfo.url
#params['rev'] = self.wcinfo.rev
#params['long_description'] = reformat(params['long_description'])
#print py.std.pprint.pprint(params)
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, py_modules=['_findpy',]),
#self.append_pprint(indent, scripts=self.getscripts())
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, data_files=self.getdatafiles())
self.append_pprint(indent, package_data=self.getpackagedata())
#self.append_pprint(indent, package_dir={'py': 'py'})
#self.append_pprint(indent, packages=self.getpackages())
if self.setuptools:
self.append_pprint(indent, zip_safe=False)
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()