# HG changeset patch # User Denis Laxalde <denis.laxalde@logilab.fr> # Date 1526978219 -7200 # Tue May 22 10:36:59 2018 +0200 # Node ID 6ea7e3c1d6e0ca9501b94d88ce6add3f77c29a01 # Parent 7db058f4d66eda9ff75cc2a9371ca94b6b7b0ca6 [pkg] Make cube Python3-installable We refresh setup.py and __pkginfo__.py using CubicWeb 3.23 skeleton which is Python3 compatible and still use the legacy layout. diff --git a/__pkginfo__.py b/__pkginfo__.py --- a/__pkginfo__.py +++ b/__pkginfo__.py @@ -1,6 +1,11 @@ # pylint: disable=W0622 """cubicweb-squareui application packaging information""" +from os import listdir as _listdir +from os.path import join, isdir +from glob import glob + + modname = 'squareui' distname = 'cubicweb-squareui' @@ -23,28 +28,25 @@ 'Framework :: CubicWeb', 'Programming Language :: Python', 'Programming Language :: JavaScript', - ] - -from os import listdir as _listdir -from os.path import join, isdir -from glob import glob +] THIS_CUBE_DIR = join('share', 'cubicweb', 'cubes', modname) + def listdir(dirpath): return [join(dirpath, fname) for fname in _listdir(dirpath) - if fname[0] != '.' and not fname.endswith('.pyc') - and not fname.endswith('~') - and not isdir(join(dirpath, fname))] + if fname[0] != '.' and not fname.endswith('.pyc') and + not fname.endswith('~') and + not isdir(join(dirpath, fname))] data_files = [ # common files [THIS_CUBE_DIR, [fname for fname in glob('*.py') if fname != 'setup.py']], - ] +] # check for possible extended cube layout -for dname in ('entities', 'views', 'sobjects', 'hooks', 'schema', 'data', 'wdoc', 'i18n', 'migration'): +for dname in ('entities', 'views', 'sobjects', 'hooks', 'schema', 'data', + 'wdoc', 'i18n', 'migration'): if isdir(dname): data_files.append([join(THIS_CUBE_DIR, dname), listdir(dname)]) # Note: here, you'll need to add subdirectories if you want # them to be included in the debian package - diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -1,10 +1,10 @@ #!/usr/bin/env python # pylint: disable=W0142,W0403,W0404,W0613,W0622,W0622,W0704,R0904,C0103,E0611 # -# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # -# This file is part of CubicWeb tag cube. +# This file is part of a CubicWeb cube. # # CubicWeb is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free @@ -16,8 +16,8 @@ # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # -# You should have received a copy of the GNU Lesser General Public License along -# with CubicWeb. If not, see <http://www.gnu.org/licenses/>. +# You should have received a copy of the GNU Lesser General Public License +# along with CubicWeb. If not, see <http://www.gnu.org/licenses/>. """Generic Setup script, takes package info from __pkginfo__.py file """ __docformat__ = "restructuredtext en" @@ -25,11 +25,11 @@ import os import sys import shutil -from os.path import isdir, exists, join, walk +from os.path import exists, join, dirname try: if os.environ.get('NO_SETUPTOOLS'): - raise ImportError() # do as there is no setuptools + raise ImportError() # do as there is no setuptools from setuptools import setup from setuptools.command import install_lib USE_SETUPTOOLS = True @@ -39,34 +39,45 @@ USE_SETUPTOOLS = False from distutils.command import install_data -# import required features -from __pkginfo__ import modname, version, license, description, web, \ - author, author_email, classifiers + +# load metadata from the __pkginfo__.py file so there is no risk of conflict +# see https://packaging.python.org/en/latest/single_source_version.html +base_dir = dirname(__file__) +pkginfo = {} +with open(join(base_dir, "__pkginfo__.py")) as f: + exec(f.read(), pkginfo) -if exists('README'): - long_description = file('README').read() -else: - long_description = '' +# get required metadatas +modname = pkginfo['modname'] +version = pkginfo['version'] +license = pkginfo['license'] +description = pkginfo['description'] +web = pkginfo['web'] +author = pkginfo['author'] +author_email = pkginfo['author_email'] +classifiers = pkginfo['classifiers'] -# import optional features -import __pkginfo__ +with open(join(base_dir, 'README')) as f: + long_description = f.read() + +# get optional metadatas +distname = pkginfo.get('distname', modname) +scripts = pkginfo.get('scripts', ()) +include_dirs = pkginfo.get('include_dirs', ()) +data_files = pkginfo.get('data_files', None) +ext_modules = pkginfo.get('ext_modules', None) +dependency_links = pkginfo.get('dependency_links', ()) + if USE_SETUPTOOLS: requires = {} - for entry in ("__depends__",): # "__recommends__"): - requires.update(getattr(__pkginfo__, entry, {})) + for entry in ("__depends__",): # "__recommends__"): + requires.update(pkginfo.get(entry, {})) install_requires = [("%s %s" % (d, v and v or "")).strip() - for d, v in requires.iteritems()] + for d, v in requires.items()] else: install_requires = [] -distname = getattr(__pkginfo__, 'distname', modname) -scripts = getattr(__pkginfo__, 'scripts', ()) -include_dirs = getattr(__pkginfo__, 'include_dirs', ()) -data_files = getattr(__pkginfo__, 'data_files', None) -ext_modules = getattr(__pkginfo__, 'ext_modules', None) -dependency_links = getattr(__pkginfo__, 'dependency_links', ()) - -BASE_BLACKLIST = ('CVS', '.svn', '.hg', 'debian', 'dist', 'build') +BASE_BLACKLIST = ('CVS', '.svn', '.hg', '.git', 'debian', 'dist', 'build') IGNORED_EXTENSIONS = ('.pyc', '.pyo', '.elc', '~') @@ -82,45 +93,41 @@ scripts_ = linux_scripts return scripts_ + def export(from_dir, to_dir, blacklist=BASE_BLACKLIST, ignore_ext=IGNORED_EXTENSIONS, verbose=True): - """make a mirror of from_dir in to_dir, omitting directories and files - listed in the black list - """ - def make_mirror(arg, directory, fnames): - """walk handler""" + try: + os.mkdir(to_dir) + except OSError as ex: + # file exists ? + import errno + if ex.errno != errno.EEXIST: + raise + for dirpath, dirnames, filenames in os.walk(from_dir): for norecurs in blacklist: try: - fnames.remove(norecurs) + dirnames.remove(norecurs) except ValueError: pass - for filename in fnames: + for dir_name in dirnames: + dest = join(to_dir, dir_name) + if not exists(dest): + os.mkdir(dest) + for filename in filenames: # don't include binary files + src = join(dirpath, filename) + dest = to_dir + src[len(from_dir):] if filename[-4:] in ignore_ext: continue if filename[-1] == '~': continue - src = join(directory, filename) - dest = to_dir + src[len(from_dir):] + if exists(dest): + os.remove(dest) if verbose: sys.stderr.write('%s -> %s\n' % (src, dest)) - if os.path.isdir(src): - if not exists(dest): - os.mkdir(dest) - else: - if exists(dest): - os.remove(dest) - shutil.copy2(src, dest) - try: - os.mkdir(to_dir) - except OSError, ex: - # file exists ? - import errno - if ex.errno != errno.EEXIST: - raise - walk(from_dir, make_mirror, None) + shutil.copy2(src, dest) class MyInstallLib(install_lib.install_lib): @@ -137,6 +144,7 @@ dest = join(self.install_dir, base, directory) export(directory, dest, verbose=False) + # re-enable copying data files in sys.prefix old_install_data = install_data.install_data if USE_SETUPTOOLS: @@ -150,13 +158,15 @@ old_install_data.run(self) self.install_dir = _old_install_dir try: - import setuptools.command.easy_install # only if easy_install avaible + # only if easy_install available + import setuptools.command.easy_install # noqa # monkey patch: Crack SandboxViolation verification from setuptools.sandbox import DirectorySandbox as DS old_ok = DS._ok + def _ok(self, path): """Return True if ``path`` can be written during installation.""" - out = old_ok(self, path) # here for side effect from setuptools + out = old_ok(self, path) # here for side effect from setuptools realpath = os.path.normcase(os.path.realpath(path)) allowed_path = os.path.normcase(sys.prefix) if realpath.startswith(allowed_path): @@ -166,6 +176,7 @@ except ImportError: pass + def install(**kwargs): """setup entry point""" if USE_SETUPTOOLS: @@ -181,21 +192,22 @@ kwargs['zip_safe'] = False cmdclass['install_data'] = MyInstallData - return setup(name = distname, - version = version, - license = license, - description = description, - long_description = long_description, - author = author, - author_email = author_email, - url = web, - scripts = ensure_scripts(scripts), - data_files = data_files, - ext_modules = ext_modules, - cmdclass = cmdclass, - classifiers = classifiers, + return setup(name=distname, + version=version, + license=license, + description=description, + long_description=long_description, + author=author, + author_email=author_email, + url=web, + scripts=ensure_scripts(scripts), + data_files=data_files, + ext_modules=ext_modules, + cmdclass=cmdclass, + classifiers=classifiers, **kwargs ) -if __name__ == '__main__' : + +if __name__ == '__main__': install()