[PATCH 1 of 5 seo] New style cube and switch to py3

Noé Gaumont noe.gaumont at logilab.fr
Thu Mar 5 15:00:41 CET 2020


Minor remark on copyright that should extends to 2020 instead of 2016.

Otherwise LGTM

Le 05/03/2020 à 14:54, Philippe Pepiot a écrit :
> # HG changeset patch
> # User Philippe Pepiot <philippe.pepiot at logilab.fr>
> # Date 1583332228 -3600
> #      Wed Mar 04 15:30:28 2020 +0100
> # Node ID 13218d4b4c5fd6636ccaf6eab09f08997b1d4ea9
> # Parent  6a598ef1fc395147d0ea9faeb0b7cac9eced7f80
> New style cube and switch to py3
>
> * Switch to new style cube "cubicweb_seo"
> * drop useless test/pytestconf.py file
> * refresh debian packaging for python3 using pybuild
> * fix missing files in MANIFEST.in
>
> diff --git a/MANIFEST.in b/MANIFEST.in
> --- a/MANIFEST.in
> +++ b/MANIFEST.in
> @@ -1,5 +1,10 @@
> +include README
>   include *.py
>   include */*.py
> -recursive-include data *.gif *.png *.ico *.css *.js
> -recursive-include i18n *.po
> -recursive-include wdoc *
> +recursive-include cubicweb_seo *.py
> +recursive-include cubicweb_seo/data *.gif *.png *.jpg *.ico *.css *.js
> +recursive-include cubicweb_seo/i18n *.po
> +recursive-include test/data bootstrap_cubes *.py
> +
> +include tox.ini
> +prune debian
> diff --git a/__init__.py b/cubicweb_seo/__init__.py
> rename from __init__.py
> rename to cubicweb_seo/__init__.py
> diff --git a/__pkginfo__.py b/cubicweb_seo/__pkginfo__.py
> rename from __pkginfo__.py
> rename to cubicweb_seo/__pkginfo__.py
> --- a/__pkginfo__.py
> +++ b/cubicweb_seo/__pkginfo__.py
> @@ -13,7 +13,9 @@ author_email = 'contact at logilab.fr'
>   description = 'search engine optimisation with robotstxt and sitemaps'
>   web = 'http://www.cubicweb.org/project/%s' % distname
>   
> -__depends__ =  {'cubicweb': '>= 3.15.5'}
> +__depends__ = {
> +    'cubicweb': '>= 3.24',
> +}
>   __recommends__ = {}
>   
>   classifiers = [
> @@ -21,28 +23,4 @@ classifiers = [
>       '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))]
> -
> -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'):
> -    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/i18n/en.po b/cubicweb_seo/i18n/en.po
> rename from i18n/en.po
> rename to cubicweb_seo/i18n/en.po
> diff --git a/i18n/es.po b/cubicweb_seo/i18n/es.po
> rename from i18n/es.po
> rename to cubicweb_seo/i18n/es.po
> diff --git a/i18n/fr.po b/cubicweb_seo/i18n/fr.po
> rename from i18n/fr.po
> rename to cubicweb_seo/i18n/fr.po
> diff --git a/views.py b/cubicweb_seo/views.py
> rename from views.py
> rename to cubicweb_seo/views.py
> --- a/views.py
> +++ b/cubicweb_seo/views.py
> @@ -45,7 +45,7 @@ class RobotsRule(AppObject):
>   
>       A custom rule should be built by extending this class. For instance::
>   
> -      from cubes.seo.views import RobotsRule
> +      from cubicweb_seo.views import RobotsRule
>   
>         class VcsfileRobotsRule(RobotsRule):
>             __regid__ = 'vcsfile'
> @@ -109,7 +109,7 @@ class SitemapRule(AppObject):
>   
>       A custom rule should be built by extending this class. For instance::
>   
> -      from cubes.seo.views import SitemapRule
> +      from cubicweb_seo.views import SitemapRule
>   
>         class CardSitemapRule(SitemapRule):
>             __regid__ = 'card'
> diff --git a/debian/control b/debian/control
> --- a/debian/control
> +++ b/debian/control
> @@ -4,13 +4,18 @@ Priority: optional
>   Maintainer: LOGILAB S.A. (Paris, FRANCE) <contact at logilab.fr>
>   Homepage: http://www.cubicweb.org/project/cubicweb-seo
>   Uploaders: Nicolas Chauvat <nicolas.chauvat at logilab.fr>
> -Build-Depends: debhelper (>= 7), python (>=2.5), python-support
> +Build-Depends:
> + debhelper (>= 9),
> + python3-all,
> + dh-python
>   Standards-Version: 3.9.3
> -XS-Python-Version: >= 2.5
> +X-Python3-Version: >= 3.5
>   
> -Package: cubicweb-seo
> +Package: python3-cubicweb-seo
>   Architecture: all
> -Depends: cubicweb-common (>= 3.15.5), ${python:Depends}
> +Depends:
> + ${python3:Depends}
> + ${misc:Depends}
>   Description: search engine optimisation with robotstxt and sitemaps
>    CubicWeb is a semantic web application framework.
>    .
> diff --git a/debian/rules b/debian/rules
> --- a/debian/rules
> +++ b/debian/rules
> @@ -1,57 +1,4 @@
>   #!/usr/bin/make -f
> -# Sample debian/rules that uses debhelper.
> -# GNU copyright 1997 to 1999 by Joey Hess.
> -
> -# Uncomment this to turn on verbose mode.
> -#export DH_VERBOSE=1
> -build: build-arch build-indep
> -build-arch:
> -	# Nothing to do
> -build-indep: build-stamp
> -build-stamp:
> -	dh_testdir
> -	NO_SETUPTOOLS=1 python setup.py -q build
> -	touch build-stamp
> -
> -clean:
> -	dh_testdir
> -	dh_testroot
> -	rm -f build-stamp configure-stamp
> -	rm -rf build
> -	find . -name "*.pyc" | xargs rm -f
> -	dh_clean
>   
> -install: build
> -	dh_testdir
> -	dh_testroot
> -	dh_clean -k
> -	dh_installdirs -i
> -	NO_SETUPTOOLS=1 python setup.py -q install --no-compile --prefix=debian/cubicweb-seo/usr/
> -	# remove generated .egg-info file
> -	rm -rf debian/cubicweb-seo/usr/lib/python*
> -
> -
> -# Build architecture-independent files here.
> -binary-indep: build install
> -	dh_testdir
> -	dh_testroot
> -	dh_install -i
> -	dh_installchangelogs -i
> -	dh_installexamples -i
> -	dh_installdocs -i
> -	dh_installman -i
> -	dh_pysupport -i /usr/share/cubicweb
> -	dh_link -i
> -	dh_compress -i -X.py -X.ini -X.xml -Xtest
> -	dh_fixperms -i
> -	dh_installdeb -i
> -	dh_gencontrol -i
> -	dh_md5sums -i
> -	dh_builddeb -i
> -
> -
> -# Build architecture-dependent files here.
> -binary-arch:
> -
> -binary: binary-indep
> -.PHONY: build clean binary-arch binary-indep binary
> +%:
> +	dh $@ --with python3 --buildsystem=pybuild
> 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-2014 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 at logilab.fr
>   #
> -# This file is part of CubicWeb tag cube.
> +# This file is part of a cubicweb-seo
>   #
>   # 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,186 +16,67 @@
>   # 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/>.
> -"""Generic Setup script, takes package info from __pkginfo__.py file
> +# You should have received a copy of the GNU Lesser General Public License
> +# along with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
> +"""cubicweb_seo setup module using data from
> +cubicweb_seo/__pkginfo__.py file
>   """
> -__docformat__ = "restructuredtext en"
> -
> -import os
> -import sys
> -import shutil
> -from os.path import isdir, exists, join, walk
> -
> -try:
> -    if os.environ.get('NO_SETUPTOOLS'):
> -        raise ImportError() # do as there is no setuptools
> -    from setuptools import setup
> -    from setuptools.command import install_lib
> -    USE_SETUPTOOLS = True
> -except ImportError:
> -    from distutils.core import setup
> -    from distutils.command import install_lib
> -    USE_SETUPTOOLS = False
> -from distutils.command import install_data
>   
> -# import required features
> -from __pkginfo__ import modname, version, license, description, web, \
> -     author, author_email, classifiers
> -
> -if exists('README'):
> -    long_description = file('README').read()
> -else:
> -    long_description = ''
> +from os.path import join, dirname
>   
> -# import optional features
> -import __pkginfo__
> -if USE_SETUPTOOLS:
> -    requires = {}
> -    for entry in ("__depends__",): # "__recommends__"):
> -        requires.update(getattr(__pkginfo__, entry, {}))
> -    install_requires = [("%s %s" % (d, v and v or "")).strip()
> -                       for d, v in requires.iteritems()]
> -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')
> -IGNORED_EXTENSIONS = ('.pyc', '.pyo', '.elc', '~')
> +from setuptools import find_packages, setup
>   
>   
> -def ensure_scripts(linux_scripts):
> -    """
> -    Creates the proper script names required for each platform
> -    (taken from 4Suite)
> -    """
> -    from distutils import util
> -    if util.get_platform()[:3] == 'win':
> -        scripts_ = [script + '.bat' for script in linux_scripts]
> -    else:
> -        scripts_ = linux_scripts
> -    return scripts_
> +here = dirname(__file__)
> +
> +# 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
> +pkginfo = join(here, 'cubicweb_seo', '__pkginfo__.py')
> +__pkginfo__ = {}
> +with open(pkginfo) as f:
> +    exec(f.read(), __pkginfo__)
>   
> -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"""
> -        for norecurs in blacklist:
> -            try:
> -                fnames.remove(norecurs)
> -            except ValueError:
> -                pass
> -        for filename in fnames:
> -            # don't include binary files
> -            if filename[-4:] in ignore_ext:
> -                continue
> -            if filename[-1] == '~':
> -                continue
> -            src = join(directory, filename)
> -            dest = to_dir + src[len(from_dir):]
> -            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)
> +# get required metadatas
> +distname = __pkginfo__['distname']
> +version = __pkginfo__['version']
> +license = __pkginfo__['license']
> +description = __pkginfo__['description']
> +web = __pkginfo__['web']
> +author = __pkginfo__['author']
> +author_email = __pkginfo__['author_email']
> +classifiers = __pkginfo__['classifiers']
> +
> +with open(join(here, 'README')) as f:
> +    long_description = f.read()
> +
> +# get optional metadatas
> +data_files = __pkginfo__.get('data_files', None)
> +dependency_links = __pkginfo__.get('dependency_links', ())
> +
> +requires = {}
> +for entry in ("__depends__",):  # "__recommends__"):
> +    requires.update(__pkginfo__.get(entry, {}))
> +install_requires = ["{0} {1}".format(d, v and v or "").strip()
> +                    for d, v in requires.items()]
>   
>   
> -class MyInstallLib(install_lib.install_lib):
> -    """extend install_lib command to handle  package __init__.py and
> -    include_dirs variable if necessary
> -    """
> -    def run(self):
> -        """overridden from install_lib class"""
> -        install_lib.install_lib.run(self)
> -        # manually install included directories if any
> -        if include_dirs:
> -            base = modname
> -            for directory in include_dirs:
> -                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:
> -    # overwrite InstallData to use sys.prefix instead of the egg directory
> -    class MyInstallData(old_install_data):
> -        """A class that manages data files installation"""
> -        def run(self):
> -            _old_install_dir = self.install_dir
> -            if self.install_dir.endswith('egg'):
> -                self.install_dir = sys.prefix
> -            old_install_data.run(self)
> -            self.install_dir = _old_install_dir
> -    try:
> -        import setuptools.command.easy_install # only if easy_install avaible
> -        # 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
> -            realpath = os.path.normcase(os.path.realpath(path))
> -            allowed_path = os.path.normcase(sys.prefix)
> -            if realpath.startswith(allowed_path):
> -                out = True
> -            return out
> -        DS._ok = _ok
> -    except ImportError:
> -        pass
> -
> -def install(**kwargs):
> -    """setup entry point"""
> -    if USE_SETUPTOOLS:
> -        if '--force-manifest' in sys.argv:
> -            sys.argv.remove('--force-manifest')
> -    # install-layout option was introduced in 2.5.3-1~exp1
> -    elif sys.version_info < (2, 5, 4) and '--install-layout=deb' in sys.argv:
> -        sys.argv.remove('--install-layout=deb')
> -    cmdclass = {'install_lib': MyInstallLib}
> -    if USE_SETUPTOOLS:
> -        kwargs['install_requires'] = install_requires
> -        kwargs['dependency_links'] = dependency_links
> -        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,
> -                 **kwargs
> -                 )
> -
> -if __name__ == '__main__' :
> -    install()
> +setup(
> +    name=distname,
> +    version=version,
> +    license=license,
> +    description=description,
> +    long_description=long_description,
> +    author=author,
> +    author_email=author_email,
> +    url=web,
> +    classifiers=classifiers,
> +    packages=find_packages(exclude=['test']),
> +    install_requires=install_requires,
> +    include_package_data=True,
> +    entry_points={
> +        'cubicweb.cubes': [
> +            'seo=cubicweb_seo',
> +        ],
> +    },
> +    zip_safe=False,
> +)
> diff --git a/test/pytestconf.py b/test/pytestconf.py
> deleted file mode 100644
> --- a/test/pytestconf.py
> +++ /dev/null
> @@ -1,60 +0,0 @@
> -# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
> -# contact http://www.logilab.fr/ -- mailto:contact at logilab.fr
> -#
> -# This file is part of CubicWeb.
> -#
> -# 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
> -# Software Foundation, either version 2.1 of the License, or (at your option)
> -# any later version.
> -#
> -# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
> -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
> -# 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/>.
> -"""
> -
> -"""
> -import os
> -import sys
> -
> -from logilab.common.pytest import PyTester
> -
> -def getlogin():
> -    """avoid usinng os.getlogin() because of strange tty / stdin problems
> -    (man 3 getlogin)
> -    Another solution would be to use $LOGNAME, $USER or $USERNAME
> -    """
> -    if sys.platform == 'win32':
> -        return os.environ.get('USERNAME') or 'cubicweb'
> -    import pwd
> -    return pwd.getpwuid(os.getuid())[0]
> -
> -
> -def update_parser(parser):
> -    login = getlogin()
> -    parser.add_option('-r', '--rebuild-database', dest='rebuild_db',
> -                      default=False, action="store_true",
> -                      help="remove tmpdb and rebuilds the test database")
> -    parser.add_option('-u', '--dbuser', dest='dbuser', action='store',
> -                      default=login, help="database user")
> -    parser.add_option('-w', '--dbpassword', dest='dbpassword', action='store',
> -                      default=login, help="database user's password")
> -    parser.add_option('-n', '--dbname', dest='dbname', action='store',
> -                      default=None, help="database name")
> -    parser.add_option('--euser', dest='euser', action='store',
> -                      default=login, help="euser name")
> -    parser.add_option('--epassword', dest='epassword', action='store',
> -                      default=login, help="euser's password' name")
> -    return parser
> -
> -
> -class CustomPyTester(PyTester):
> -    def __init__(self, cvg, options):
> -        super(CustomPyTester, self).__init__(cvg, options)
> -        if options.rebuild_db:
> -            os.unlink('tmpdb')
> -            os.unlink('tmpdb-template')
> diff --git a/test/unittest_views.py b/test/unittest_views.py
> --- a/test/unittest_views.py
> +++ b/test/unittest_views.py
> @@ -27,7 +27,7 @@ from lxml import etree
>   
>   from cubicweb.devtools.testlib import CubicWebTC
>   
> -from cubes.seo.views import SitemapRule
> +from cubicweb_seo.views import SitemapRule
>   
>   SITEMAP_NS = '{http://www.sitemaps.org/schemas/sitemap/0.9}'
>   
>



More information about the cubicweb-devel mailing list