From 66f475baa9ec50ee3a2160c99dcb962f5822f4e4 Mon Sep 17 00:00:00 2001 From: Anatoly Bubenkov Date: Tue, 17 Mar 2015 22:35:53 +0100 Subject: [PATCH] test suite fixes --- .DS_Store | Bin 0 -> 6148 bytes .gitignore | 3 +- CHANGES.rst | 6 + CONTRIBUTORS.rst | 1 + LICENSE.txt | 20 +++ Makefile | 11 ++ README.rst | 150 +++++++++++++++++- bootstrap.py | 83 ++++++---- collective/recipe/pip/README.rst | 132 --------------- collective/recipe/pip/__init__.py | 6 +- setup.py | 80 +++++----- .../recipe/pip/tests => tests}/__init__.py | 0 .../recipe/pip/tests => tests}/test_docs.py | 4 +- tox.ini | 3 +- 14 files changed, 287 insertions(+), 212 deletions(-) create mode 100644 .DS_Store create mode 100644 LICENSE.txt create mode 100644 Makefile delete mode 100644 collective/recipe/pip/README.rst rename {collective/recipe/pip/tests => tests}/__init__.py (100%) rename {collective/recipe/pip/tests => tests}/test_docs.py (96%) diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..e1638f1221db5f99d4f7f810bfb38f39aa647d9a GIT binary patch literal 6148 zcmeHKu};G<5WRy8l~_6;0h{>&q)x0+6(sil08)y|K$J?f5~F{EiIJ6&uYk{CT!EefxU*@KBSWuU0aw5k*eSsCA)pY; zjL|S19jH7%E?v(fc6+W5KB!5Wpo-5!A{4)i#s20^6o62|V-u8Ic29z5V r8s|keU}z710?^?(a+;jx4{T#znK2r26^GyAYQowzo5Vuju1c9 literal 0 HcmV?d00001 diff --git a/.gitignore b/.gitignore index 513f8f0..260bd73 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,8 @@ .idea /*.sublime-workspace .codeintel - +/.env +/.eggs # C extensions *.so diff --git a/CHANGES.rst b/CHANGES.rst index b94d25d..4f26330 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +0.3.0 (2015-03-17) +------------------ + +- Support recent pip (ridha) + + 0.2.0 (2014-02-06) ------------------ diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index dca492a..dab0656 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -3,3 +3,4 @@ Contributors Anatoly Bubenkov , Author +Abdul Kader Maliyakkal , Contributor diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..d4fe285 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) Anatoly Bubenkov and others + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5def6be --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +# create virtual environment +.env: + virtualenv .env + +# install all needed for development +develop: .env + .env/bin/pip install -e . -r requirements-testing.txt tox + +# clean the development envrironment +clean: + -rm -rf .env diff --git a/README.rst b/README.rst index 81a1687..3066926 100644 --- a/README.rst +++ b/README.rst @@ -12,5 +12,153 @@ and buildout for same project independently :target: https://coveralls.io/r/collective/collective.recipe.pip -See `Doc tests `_. +Overview +======== +This recipe allows to parse pip configuration files (usually named requirements.txt) into just list of the eggs to use +in other parts of the buildout. + +The recipe mirrors the parsed eggs list into its section, so that e.g. +``${pip:eggs}`` will give the list of parsed eggs. + +The list of eggs which come from urls (eg from github) are also exported to the urls param: +``${pip:urls}`` will give the list of parsed egg urls. + + +For now single option of the recipe is ``configs`` - list of config files to parse. + +The config files are parsed during the initialization of the ``Recipe`` instance, +i.e. after ``buildout.cfg`` is read but before any recipe is installed or updated. + + +Example usage: Use an environment variable +========================================== + +Let's create test config files + + >>> write('requirements.txt', + ... """ + ... some.egg + ... -e http://some.package.git.url#egg=develop.egg + ... --use-wheel + ... http://sourceforge.net/projects/pychecker/files/latest/download?source=files#egg=pychecker==0.8.19 + ... fabric>=0.9b1 + ... # some comment + ... xlrd # reading excel worksheets + ... html5lib==0.95 + ... """) + + >>> write('requirements-included.txt', + ... """ + ... some.included.egg + ... """) + + >>> write('requirements-included2.txt', + ... """ + ... some.included.egg2 + ... """) + + >>> mkdir('file.package') + >>> write('file.package/setup.py', + ... """ + ... from setuptools import setup + ... setup(name='file.package') + ... """) + + >>> write('requirements2.txt', + ... """ + ... -r requirements-included.txt + ... --requirement requirements-included2.txt + ... some2.egg + ... django>=1.3,<1.4 + ... django-extensions #django extension requirements (not mandatory, but useful on dev) + ... -e http://some2.package.git.url#egg=develop2.egg + ... -e file.package + ... --extra-index-url=http://some.index.url + ... -f http://git.fabfile.org + ... """) + + +We'll start by creating a buildout that uses the recipe:: + + >>> write('buildout.cfg', + ... r""" + ... [buildout] + ... parts = pip print + ... + ... [some-section] + ... eggs = ${pip:eggs} + ... + ... [pip] + ... recipe = collective.recipe.pip + ... configs = requirements.txt + ... requirements2.txt + ... versions = versions + ... + ... [versions] + ... + ... [print] + ... recipe = mr.scripty + ... install = + ... ... print(self.buildout['some-section']['eggs']) + ... ... print('\n[versions]') + ... ... print('\n'.join(i + ' = ' + k for i, k in sorted(self.buildout['versions'].items()))) + ... ... print('\n[urls]') + ... ... print(self.buildout['pip']['urls']) + ... ... print('# done') + ... ... return [] + ... """) + +The `mr.scripty` recipe is used to print out the value of the ${some-section:some-option} +option. + +Running the buildout gives us:: + + >>> import sys + >>> sys.stdout.write('start\n' + system(buildout)) + start... + Installing pip. + Installing print. + develop.egg + develop2.egg + django-extensions + django>=1.3,<1.4 + fabric>=0.9b1 + html5lib==0.95 + pychecker==0.8.19 + some.egg + some.included.egg + some.included.egg2 + some2.egg + xlrd + [versions] + django = >=1.3,<1.4 + fabric = >=0.9b1 + html5lib = 0.95 + pychecker = 0.8.19 + zc.buildout = ... + zc.recipe.egg = ... + [urls] + /sample-buildout/file.package + git+http://some.package.git.url#egg=develop.egg + git+http://some2.package.git.url#egg=develop2.egg + http://sourceforge.net/projects/pychecker/files/latest/download?source=files#egg=pychecker==0.8.19 + ... + + +Contact +------- + +If you have questions, bug reports, suggestions, etc. please create an issue on +the `GitHub project page `_. + + +License +------- + +This software is licensed under the `MIT license `_ + +See `License file `_ + + +© 2013 Anatoly Bubenkov and others. diff --git a/bootstrap.py b/bootstrap.py index 4d7aa17..a629566 100644 --- a/bootstrap.py +++ b/bootstrap.py @@ -35,7 +35,7 @@ Simply run this script in a directory containing a buildout.cfg, using the Python that you want bin/buildout to use. -Note that by using --find-links to point to local resources, you can keep +Note that by using --find-links to point to local resources, you can keep this script from going over the network. ''' @@ -56,6 +56,11 @@ "file to be used.")) parser.add_option("-f", "--find-links", help=("Specify a URL to search for buildout releases")) +parser.add_option("--allow-site-packages", + action="store_true", default=False, + help=("Let bootstrap.py use existing site packages")) +parser.add_option("--setuptools-version", + help="use a specific setuptools version") options, args = parser.parse_args() @@ -63,32 +68,42 @@ ###################################################################### # load/install setuptools -to_reload = False try: - import pkg_resources - import setuptools + if options.allow_site_packages: + import setuptools + import pkg_resources + from urllib.request import urlopen except ImportError: - ez = {} - - try: - from urllib.request import urlopen - except ImportError: - from urllib2 import urlopen - - # XXX use a more permanent ez_setup.py URL when available. - exec(urlopen('https://bitbucket.org/pypa/setuptools/raw/0.7.2/ez_setup.py' - ).read(), ez) - setup_args = dict(to_dir=tmpeggs, download_delay=0) - ez['use_setuptools'](**setup_args) - - if to_reload: - reload(pkg_resources) - import pkg_resources - # This does not (always?) update the default working set. We will - # do it. - for path in sys.path: - if path not in pkg_resources.working_set.entries: - pkg_resources.working_set.add_entry(path) + from urllib2 import urlopen + +ez = {} +exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez) + +if not options.allow_site_packages: + # ez_setup imports site, which adds site packages + # this will remove them from the path to ensure that incompatible versions + # of setuptools are not in the path + import site + # inside a virtualenv, there is no 'getsitepackages'. + # We can't remove these reliably + if hasattr(site, 'getsitepackages'): + for sitepackage_path in site.getsitepackages(): + sys.path[:] = [x for x in sys.path if sitepackage_path not in x] + +setup_args = dict(to_dir=tmpeggs, download_delay=0) + +if options.setuptools_version is not None: + setup_args['version'] = options.setuptools_version + +ez['use_setuptools'](**setup_args) +import setuptools +import pkg_resources + +# This does not (always?) update the default working set. We will +# do it. +for path in sys.path: + if path not in pkg_resources.working_set.entries: + pkg_resources.working_set.add_entry(path) ###################################################################### # Install buildout @@ -119,10 +134,15 @@ _final_parts = '*final-', '*final' def _final_version(parsed_version): - for part in parsed_version: - if (part[:1] == '*') and (part not in _final_parts): - return False - return True + try: + return not parsed_version.is_prerelease + except AttributeError: + # Older setuptools + for part in parsed_version: + if (part[:1] == '*') and (part not in _final_parts): + return False + return True + index = setuptools.package_index.PackageIndex( search_path=[setuptools_path]) if find_links: @@ -149,8 +169,7 @@ def _final_version(parsed_version): import subprocess if subprocess.call(cmd, env=dict(os.environ, PYTHONPATH=setuptools_path)) != 0: raise Exception( - "Failed to execute command:\n%s", - repr(cmd)[1:-1]) + "Failed to execute command:\n%s" % repr(cmd)[1:-1]) ###################################################################### # Import and run buildout @@ -167,4 +186,4 @@ def _final_version(parsed_version): args[0:0] = ['-c', options.config_file] zc.buildout.buildout.main(args) -shutil.rmtree(tmpeggs) \ No newline at end of file +shutil.rmtree(tmpeggs) diff --git a/collective/recipe/pip/README.rst b/collective/recipe/pip/README.rst deleted file mode 100644 index 6c631c1..0000000 --- a/collective/recipe/pip/README.rst +++ /dev/null @@ -1,132 +0,0 @@ -Overview -======== - -This recipe allows to parse pip configuration files (usually named requirements.txt) into just list of the eggs to use -in other parts of the buildout. - -The recipe mirrors the parsed eggs list into its section, so that e.g. -``${pip:eggs}`` will give the list of parsed eggs. - -The list of eggs which come from urls (eg from github) are also exported to the urls param: -``${pip:urls}`` will give the list of parsed egg urls. - - -For now single option of the recipe is ``configs`` - list of config files to parse. - -The config files are parsed during the initialization of the ``Recipe`` instance, -i.e. after ``buildout.cfg`` is read but before any recipe is installed or updated. - - -Example usage: Use an environment variable -========================================== - -Let's create test config files - - >>> write('requirements.txt', - ... """ - ... some.egg - ... -e http://some.package.git.url#egg=develop.egg - ... --use-wheel - ... http://sourceforge.net/projects/pychecker/files/latest/download?source=files#egg=pychecker==0.8.19 - ... fabric>=0.9b1 - ... # some comment - ... xlrd # reading excel worksheets - ... html5lib==0.95 - ... """) - - >>> write('requirements-included.txt', - ... """ - ... some.included.egg - ... """) - - >>> write('requirements-included2.txt', - ... """ - ... some.included.egg2 - ... """) - - >>> mkdir('file.package') - >>> write('file.package/setup.py', - ... """ - ... from setuptools import setup - ... setup(name='file.package') - ... """) - - >>> write('requirements2.txt', - ... """ - ... -r requirements-included.txt - ... --requirement requirements-included2.txt - ... some2.egg - ... django>=1.3,<1.4 - ... django-extensions #django extension requirements (not mandatory, but useful on dev) - ... -e http://some2.package.git.url#egg=develop2.egg - ... -e file.package - ... --extra-index-url=http://some.index.url - ... -f http://git.fabfile.org - ... """) - - -We'll start by creating a buildout that uses the recipe:: - - >>> write('buildout.cfg', - ... r""" - ... [buildout] - ... parts = pip print - ... - ... [some-section] - ... eggs = ${pip:eggs} - ... - ... [pip] - ... recipe = collective.recipe.pip - ... configs = requirements.txt - ... requirements2.txt - ... versions = versions - ... - ... [versions] - ... - ... [print] - ... recipe = mr.scripty - ... install = - ... ... print self.buildout['some-section']['eggs'] - ... ... print '\n[versions]' - ... ... print '\n'.join(map(lambda (i, k): (i + ' = ' + k), sorted(self.buildout['versions'].items()))) - ... ... print '\n[urls]' - ... ... print self.buildout['pip']['urls'] - ... ... print '# done' - ... ... return [] - ... """) - -The `mr.scripty` recipe is used to print out the value of the ${some-section:some-option} -option. - -Running the buildout gives us:: - - >>> import sys - >>> sys.stdout.write('start\n' + system(buildout)) - start... - Installing pip. - Installing print. - develop.egg - develop2.egg - django-extensions - django>=1.3,<1.4 - fabric>=0.9b1 - html5lib==0.95 - pychecker==0.8.19 - some.egg - some.included.egg - some.included.egg2 - some2.egg - xlrd - [versions] - django = >=1.3,<1.4 - fabric = >=0.9b1 - html5lib = 0.95 - pychecker = 0.8.19 - zc.buildout = ... - zc.recipe.egg = ... - [urls] - /sample-buildout/file.package - git+http://some.package.git.url#egg=develop.egg - git+http://some2.package.git.url#egg=develop2.egg - http://sourceforge.net/projects/pychecker/files/latest/download?source=files#egg=pychecker==0.8.19 - ... diff --git a/collective/recipe/pip/__init__.py b/collective/recipe/pip/__init__.py index 61807d1..f58d463 100644 --- a/collective/recipe/pip/__init__.py +++ b/collective/recipe/pip/__init__.py @@ -55,8 +55,10 @@ def process(self): if requirement.editable: urls.append(requirement.url) elif requirement.url: - urls.append('{0}#egg={1}{2}'.format(requirement.url, requirement.name, specs)) - + if not '#egg=' in requirement.url: + urls.append('{0}#egg={1}{2}'.format(requirement.url, requirement.name, specs)) + else: + urls.append(requirement.url) self.options['eggs'] = "\n".join(sorted(set(eggs))) self.options['urls'] = "\n".join(sorted(set(urls))) versions_part_name = self.options.get('versions') diff --git a/setup.py b/setup.py index 4a74d03..dbf13ee 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -""" -This module contains the tool of collective.recipe.pip -""" +"""This module contains the tool of collective.recipe.pip.""" import os from setuptools import setup, find_packages @@ -9,15 +7,11 @@ def read(*rnames): return open(os.path.join(os.path.dirname(__file__), *rnames)).read() -version = '0.2.0' +version = '0.3.0' long_description = ( read('README.rst') + '\n' + - '.. contents::\n' - + '\n' + - read('collective', 'recipe', 'pip', 'README.rst') - + '\n\n' + read('CONTRIBUTORS.rst') + '\n' + read('CHANGES.rst') @@ -26,36 +20,42 @@ def read(*rnames): entry_point = 'collective.recipe.pip:Recipe' entry_points = {"zc.buildout": ["default = %s" % entry_point]} -tests_require = ['zope.testing', 'zc.buildout', 'mr.scripty', 'manuel', 'z3c.coverage', 'zope.interface'] +tests_require = [ + 'zope.testing', 'zc.buildout', 'mr.scripty', 'manuel', 'z3c.coverage', 'zope.interface'] -setup(name='collective.recipe.pip', - version=version, - description="zc.buildout recipe to parse pip config files ang use parsed info in a buildout.", - long_description=long_description, - # Get more strings from - # http://pypi.python.org/pypi?:action=list_classifiers - classifiers=[ - 'Framework :: Buildout', - 'Intended Audience :: Developers', - 'Topic :: Software Development :: Build Tools', - 'License :: OSI Approved :: GNU General Public License (GPL)', - ], - keywords='zc.buildout buildout recipe', - author='Anatoly Bubenkov', - author_email='bubenkoff@gmail.com', - url='http://github.com/collective/collective.recipe.pip', - license='GPL', - packages=find_packages(exclude=['ez_setup']), - namespace_packages=['collective', 'collective.recipe'], - include_package_data=True, - zip_safe=False, - install_requires=['setuptools', - 'zc.buildout', - 'pip', - # -*- Extra requirements: -*- - ], - tests_require=tests_require, - extras_require=dict(tests=tests_require), - test_suite='collective.recipe.pip.tests.test_docs.test_suite', - entry_points=entry_points, - ) +setup( + name='collective.recipe.pip', + version=version, + description="zc.buildout recipe to parse pip config files ang use parsed info in a buildout.", + long_description=long_description, + # Get more strings from + # http://pypi.python.org/pypi?:action=list_classifiers + classifiers=[ + 'Framework :: Buildout', + 'Intended Audience :: Developers', + 'Topic :: Software Development :: Build Tools', + 'License :: OSI Approved :: GNU General Public License (GPL)', + ], + keywords='zc.buildout buildout recipe', + author='Anatoly Bubenkov', + author_email='bubenkoff@gmail.com', + url='http://github.com/collective/collective.recipe.pip', + license='GPL', + packages=find_packages(exclude=['ez_setup']), + namespace_packages=['collective', 'collective.recipe'], + include_package_data=True, + zip_safe=False, + install_requires=[ + 'setuptools', + 'zc.buildout', + 'pip', + # -*- Extra requirements: -*- + ], + tests_require=tests_require, + extras_require=dict(tests=tests_require), + test_suite='tests.test_docs.test_suite', + entry_points=entry_points, + dependency_links=[ + 'https://github.com/minddistrict/mr.scripty/archive/4bbfa2b48b7bc8a215c80a19e61ac39d0c9545aa.zip#egg=mr.scripty' + ] +) diff --git a/collective/recipe/pip/tests/__init__.py b/tests/__init__.py similarity index 100% rename from collective/recipe/pip/tests/__init__.py rename to tests/__init__.py diff --git a/collective/recipe/pip/tests/test_docs.py b/tests/test_docs.py similarity index 96% rename from collective/recipe/pip/tests/test_docs.py rename to tests/test_docs.py index 3509d76..a86ccd9 100644 --- a/collective/recipe/pip/tests/test_docs.py +++ b/tests/test_docs.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -""" -Doctest runner for 'collective.recipe.pip'. -""" +"""Doctest runner for 'collective.recipe.pip'.""" __docformat__ = 'restructuredtext' import unittest diff --git a/tox.ini b/tox.ini index 66e46af..c685923 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,9 @@ [tox] distshare={homedir}/.tox/distshare -envlist=py26,py27 +envlist=py27,py34 indexserver= pypi = https://pypi.python.org/simple +skip_missing_interpreters = true [testenv] commands= python setup.py test