[py-svn] r57341 - py/build

hpk at codespeak.net hpk at codespeak.net
Sun Aug 17 12:51:21 CEST 2008


Author: hpk
Date: Sun Aug 17 12:51:18 2008
New Revision: 57341

Added:
   py/build/
   py/build/gensetup.py
   py/build/winpath.py
Log:
add a separate directory for building and release scripts


Added: py/build/gensetup.py
==============================================================================
--- (empty file)
+++ py/build/gensetup.py	Sun Aug 17 12:51:18 2008
@@ -0,0 +1,227 @@
+import sys
+
+sys.path.insert(0, sys.argv[1])
+import py
+
+toolpath = py.magic.autopath()
+
+def error(msg):
+    print >>sys.stderr, msg
+    raise SystemExit, 1
+
+def reformat(text):
+    return " ".join(text.split())
+
+class CollectFiles:
+    def __init__(self, wcbasedir, wcpaths):
+        self.packages = []
+        self.data_files = []
+        self._datadict = []
+        for p in wcpaths:
+            if p.check(file=1): 
+                if p.basename.startswith("py.") and p.dirpath().basename == 'bin':
+                    self.scripts.append(p.relto(wcbasedir))
+                    self.adddatafile(p)
+                elif p.ext == '.py': 
+                    self.addpythonfile(p) 
+                else: 
+                    self.adddatafile(p)
+            #else: 
+            #    if not p.listdir(): 
+            #        self.adddatafile(p.ensure('dummy'))
+
+    def adddatafile(self, p): 
+        target = self._pkgtarget.join(p.dirpath().relto(self._pkgdir))
+        l = self._datadict.setdefault(str(target), [])
+        l.append(p.relto(self._rootdir))
+
+    def addpythonfile(self, wc): 
+        p = wc.localpath
+        parts = p.parts() 
+        for above in p.parts(reverse=True)[1:]: 
+            if self._pkgdir.relto(above): 
+                dottedname = p.dirpath().relto(self._rootdir).replace(p.sep, '.')
+                if dottedname not in self.packages: 
+                    self.packages.append(dottedname) 
+                break 
+            if not above.join('__init__.py').check(): 
+                self.adddatafile(p)
+                #print "warning, added data file", p
+                break 
+
+class SetupWriter(object):
+    EXCLUDES = ("MANIFEST.in",)
+
+    def __init__(self, wcbasedir, pkg):
+        self.wcbasedir = wcbasedir
+        self.basedir = wcbasedir.localpath
+        assert self.basedir.check()
+        self.pkg = pkg
+        self.meta = pkg.__pkg__
+        self.lines = []
+        self.wcinfo = self.wcbasedir.info()
+        self.wcstatus = self.wcbasedir.status(rec=True)
+    
+    def append(self, string):
+        lines = string.split("\n")
+        while lines:
+            if not lines[0].strip():
+                lines.pop(0)
+                continue
+            break
+        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:]
+            print line
+            self.lines.append(line)
+
+    def write_winfuncs(self):
+        self.append('''
+        ''')
+
+
+    def setup_header(self):
+        tooltime = "%s %s" %(py.std.time.asctime(), py.std.time.tzname[0])
+        toolname = toolpath.basename
+        pkgname = self.pkg.__name__
+        url = self.wcinfo.url
+        rev = self.wcinfo.rev 
+        self.append('''
+            """
+                setup file for %(pkgname)r package based on:
+
+                    %(url)s, revision=%(rev)s
+
+                [auto-generated by %(toolname)s, %(tooltime)s]
+            """
+            import os, sys
+            from distutils.core import setup, Extension
+        ''' % locals())
+
+    def setup_trailer(self):
+        self.append('''
+            def main():
+                do_setup()
+                if 'install' in sys.argv[1:]:
+                    on_win32_add_to_PATH()
+            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'])
+        params['scripts'] = self.getscripts()
+        print py.std.pprint.pprint(params)
+        self.append('''
+            def do_setup():
+                setup(
+                    name=%(name)r,
+                    description=%(description)r,
+                    version=%(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, scripts=self.getscripts())
+        self.append_pprint(indent, long_description=params['long_description'])
+        self.append_pprint(indent, packages=self.getpackages())
+        self.append_pprint(indent, data_files=self.getdatafiles())
+        #self.append_pprint(indent, package_dir={'py': 'py'})
+        #self.append_pprint(indent, packages=self.getpackages())
+        self.lines.append(indent[4:] + ")\n")
+
+
+    def append_pprint(self, indent, **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] + ","
+        
+    def getscripts(self):
+        bindir = self.wcbasedir.join('py', 'bin')
+        scripts = []
+        for p in self.wcstatus.allpath():
+            if p.dirpath() == bindir and p.basename.startswith('py.'):
+                scripts.append(p.relto(self.wcbasedir))
+        return scripts
+
+    def getpackages(self):
+        packages = []
+        for p in self.wcstatus.allpath():
+            if p.check(dir=1) and p.join('__init__.py').check():
+                modpath = p.relto(self.wcbasedir).replace(p.sep, '.')
+                packages.append(modpath)
+        return packages
+
+    def getdatafiles(self):
+        datafiles = []
+        for p in self.wcstatus.allpath():
+            if p.check(file=1) and not p.ext == ".py":
+                datafiles.append(p.relto(self.wcbasedir))
+        return datafiles
+
+    def setup_win32(self):
+        import winpath
+        self.append(py.std.inspect.getsource(winpath))
+
+    def write_setup(self):
+        self.setup_header()
+        self.setup_function()
+        self.setup_win32()
+        self.setup_trailer()
+        targetfile = self.basedir.join("setup.py")
+        targetfile.write("\n".join(self.lines))
+        print "wrote",  targetfile
+
+    def write_manifest(self):
+        lines = []
+        status = self.wcstatus
+        for p in status.allpath():
+            if p.check(dir=1):
+                continue
+            toadd = p.relto(wcbasedir)
+            if toadd in self.EXCLUDES:
+                lines.append("exclude %s" %(toadd))
+            elif toadd:    
+                lines.append("include %s" %(toadd))
+        targetfile = self.basedir.join("MANIFEST.in")
+        targetfile.write("\n".join(lines))
+        print "wrote",  targetfile
+
+    def write_all(self):
+        self.write_manifest()
+        self.write_setup()
+
+if __name__ == "__main__":
+    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))
+    wcbasedir = py.path.svnwc(basedir)
+    if not wcbasedir.check(versioned=True):
+        error("not a svn working copy:%s" % basedir)
+    
+    writer = SetupWriter(wcbasedir, py)
+    writer.write_all()

Added: py/build/winpath.py
==============================================================================
--- (empty file)
+++ py/build/winpath.py	Sun Aug 17 12:51:18 2008
@@ -0,0 +1,60 @@
+
+# 
+#  some helpers to add the py lib scripts to the 
+#  WIN32 cmdline environment 
+# 
+import os, sys
+try:
+    import _winreg
+except ImportError:
+    winextensions = 0
+else:
+    winextensions = 1
+
+def on_win32_add_to_PATH():
+    if sys.platform != 'win32' or not winextensions:
+        return 
+    # Add py/bin to PATH environment variable
+    bindir = os.path.join(sysconfig.get_python_lib(), "py", "bin", "win32")
+    reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
+    key = r"SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
+    path = get_registry_value(reg, key, "Path")
+    if bindir in path:
+        return 
+    path += ";" + bindir
+    print "Setting PATH to:", path
+    set_registry_value(reg, key, "Path", path)
+    #print "Current PATH is:", get_registry_value(reg, key, "Path")
+
+    # Propagate changes to current command prompt
+    os.system("set PATH=%s" % path)
+    try_propagate_system()
+
+def try_propagate_system():
+    try:
+        import win32gui, win32con
+    except ImportError:
+        return
+    # Propagate changes throughout the system
+    win32gui.SendMessageTimeout(win32con.HWND_BROADCAST,
+        win32con.WM_SETTINGCHANGE, 0, "Environment",
+        win32con.SMTO_ABORTIFHUNG, 5000)
+
+
+    
+def get_registry_value(reg, key, value_name):
+    k = _winreg.OpenKey(reg, key)
+    value = _winreg.QueryValueEx(k, value_name)[0]
+    _winreg.CloseKey(k)
+    return value
+  
+def set_registry_value(reg, key, value_name, value):
+    k = _winreg.OpenKey(reg, key, 0, _winreg.KEY_WRITE)
+    value_type = _winreg.REG_SZ
+    # if we handle the Path value, then set its type to REG_EXPAND_SZ
+    # so that things like %SystemRoot% get automatically expanded by the
+    # command prompt
+    if value_name == "Path":
+        value_type = _winreg.REG_EXPAND_SZ
+    _winreg.SetValueEx(k, value_name, 0, value_type, value)
+    _winreg.CloseKey(k)



More information about the pytest-commit mailing list