diff options
Diffstat (limited to 'eggs/djangorecipe-0.20-py2.6.egg')
21 files changed, 1840 insertions, 0 deletions
diff --git a/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/PKG-INFO b/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/PKG-INFO new file mode 100644 index 0000000..b2a62f7 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/PKG-INFO @@ -0,0 +1,443 @@ +Metadata-Version: 1.0 +Name: djangorecipe +Version: 0.20 +Summary: Buildout recipe for Django +Home-page: https://launchpad.net/djangorecipe +Author: Jeroen Vloothuis +Author-email: jeroen.vloothuis@xs4all.nl +License: BSD +Description: Description + =========== + + This buildout recipe can be used to create a setup for Django. It will + automatically download Django and install it in the buildout's + sandbox. You can use either a release version of Django or a + subversion checkout (by using `trunk` instead of a version number. + + You can see an example of how to use the recipe below:: + + [buildout] + parts = satchmo django + eggs = ipython + + [satchmo] + recipe = gocept.download + url = http://www.satchmoproject.com/snapshots/satchmo-0.6.tar.gz + md5sum = 659a4845c1c731be5cfe29bfcc5d14b1 + + [django] + recipe = djangorecipe + version = trunk + settings = development + eggs = ${buildout:eggs} + extra-paths = + ${satchmo:location} + project = dummyshop + + + Supported options + ================= + + The recipe supports the following options. + + project + This option sets the name for your project. The recipe will create a + basic structure if the project is not already there. + + projectegg + Use this instead of the project option when you want to use an egg + as the project. This disables the generation of the project + structure. + + python + This option can be used to specify a specific Python version which can be a + different version from the one used to run the buildout. + + version + The version argument can accept a few different types of + arguments. You can specify `trunk`. In this case it will do a + checkout of the Django trunk. Another option is to specify a release + number like `0.96.2`. This will download the release + tarball. Finally you can specify a full svn url (including the + revision number). An example of this would be + `http://code.djangoproject.com/svn/django/branches/newforms-admin@7833`. + + settings + You can set the name of the settings file which is to be used with + this option. This is useful if you want to have a different + production setup from your development setup. It defaults to + `development`. + + download-cache + Set this to a folder somewhere on you system to speed up + installation. The recipe will use this folder as a cache for a + downloaded version of Django. + + extra-paths + All paths specified here will be used to extend the default Python + path for the `bin/*` scripts. + + pth-files + Adds paths found from a site `.pth` file to the extra-paths. + Useful for things like Pinax which maintains its own external_libs dir. + + control-script + The name of the script created in the bin folder. This script is the + equivalent of the `manage.py` Django normally creates. By default it + uses the name of the section (the part between the `[ ]`). + + wsgi + An extra script is generated in the bin folder when this is set to + `true`. This can be used with mod_wsgi to deploy the project. The + name of the script is `control-script.wsgi`. + + wsgilog + In case the WSGI server you're using does not allow printing to stdout, + you can set this variable to a filesystem path - all stdout/stderr data + is redirected to the log instead of printed + + fcgi + Like `wsgi` this creates an extra script within the bin folder. This + script can be used with an FCGI deployment. + + test + If you want a script in the bin folder to run all the tests for a + specific set of apps this is the option you would use. Set this to + the list of app labels which you want to be tested. + + testrunner + This is the name of the testrunner which will be created. It + defaults to `test`. + + All following options only have effect when the project specified by + the project option has not been created already. + + urlconf + You can set this to a specific url conf. It will use project.urls by + default. + + secret + The secret to use for the `settings.py`, it generates a random + string by default. + + + FCGI specific settings + ====================== + + Options for FCGI can be set within a settings file (`settings.py`). The options + is `FCGI_OPTIONS`. It should be set to a dictionary. The part below is an + example:: + + FCGI_OPTIONS = { + 'method': 'threaded', + } + + + Another example + =============== + + The next example shows you how to use some more of the options:: + + [buildout] + parts = django extras + eggs = + hashlib + + [extras] + recipe = iw.recipe.subversion + urls = + http://django-command-extensions.googlecode.com/svn/trunk/ django-command-extensions + http://django-mptt.googlecode.com/svn/trunk/ django-mptt + + [django] + recipe = djangorecipe + version = trunk + settings = development + project = exampleproject + wsgi = true + eggs = + ${buildout:eggs} + test = + someapp + anotherapp + + Example using .pth files + ======================== + + Pinax uses a .pth file to add a bunch of libraries to its path; we can + specify it's directory to get the libraries it specified added to our + path:: + + [buildout] + parts = PIL + svncode + myproject + + [PIL] + recipe = zc.recipe.egg:custom + egg = PIL + find-links = http://dist.repoze.org/ + + [svncode] + recipe = iw.recipe.subversion + urls = http://svn.pinaxproject.com/pinax/tags/0.5.1rc1 pinax + + [myproject] + recipe = djangorecipe + version = 1.0.2 + eggs = PIL + project = myproject + settings = settings + extra-paths = ${buildout:directory}/myproject/apps + ${svncode:location}/pinax/apps/external_apps + ${svncode:location}/pinax/apps/local_apps + pth-files = ${svncode:location}/pinax/libs/external_libs + wsgi = true + + Above, we use stock Pinax for pth-files and extra-paths paths for + apps, and our own project for the path that will be found first in the + list. Note that we expect our project to be checked out (e.g., by + svn:external) directly under this directory in to 'myproject'. + + Example with a different Python version + ======================================= + + To use a different Python version from the one that ran buildout in the + generated script use something like:: + + [buildout] + parts = myproject + + [special-python] + executable = /some/special/python + + [myproject] + recipe = djangorecipe + version = 1.0.2 + project = myproject + python = special-python + + + Example configuration for mod_wsgi + ================================== + + If you want to deploy a project using mod_wsgi you could use this + example as a starting point:: + + <Directory /path/to/buildout> + Order deny,allow + Allow from all + </Directory> + <VirtualHost 1.2.3.4:80> + ServerName my.rocking.server + CustomLog /var/log/apache2/my.rocking.server/access.log combined + ErrorLog /var/log/apache2/my.rocking.server/error.log + WSGIScriptAlias / /path/to/buildout/bin/django.wsgi + </VirtualHost> + + + Changes + ======= + + 0.20 + ---- + + - The recipe know makes the `django` package know to setuptools during install. + This closes #397864. Thanks to Daniel Bruce and Dan Fairs for the patch. + + - Fixed #451065 which fixes a problem with the WSGI log file option. + + - Added the posibilty to configure more FCGI related settings. Thanks to Vasily + Sulatskov for the patch. + + 0.19.2 + ------ + + - The generated WSGI & FCGI scripts are now properly removed when + options change (fixes #328182). Thanks to Horst Gutmann for the + patch. + + - Scripts are now updated when dependencies change. This fixes #44658, + thanks to Paul Carduner for the patch. + + 0.19.1 + ------ + + - Applied fix for the change in WSGI script generation. The previous + release did not work properly. + + 0.19 + ---- + + - When running again with non-newest set the recipe will no longer + update the Subversion checkout. Thanks to vinilios for the patch. + + - The WSGI and FCGI scripts are now generated using Buildout's own + system. This makes them more similar to the generated manage script + with regard to the setup of paths. Thanks to Jannis Leidel for the + patch. + + 0.18 + ---- + + - Paths from eggs and extra-paths now get precedence over the default + system path (fixes #370420). Thanks to Horst Gutmann for the patch. + + - The generated WSGI script now uses the `python` option if + present. This fixes #361695. + + 0.17.4 + ------ + + - Fixed a problem when not running in verbose mode (fixes #375151). + + 0.17.3 + ------ + + - Removed dependency on setuptools_bzr since it does not seem to work + like I expected. + + 0.17.2 + ------ + + - Changed the download code to use urllib2. This should make it work + from behind proxies (fixes #362822). Thanks to pauld for the patch. + + 0.17.1 + ------ + + - Fixed a problem with the new WSGI logging option #348797. Thanks to + Bertrand Mathieu for the patch. + + - Disable generation of the WSGI log if "wsgilog" isn't set, thanks to + Jacob Kaplan-Moss for the patch. + + - Updated buildout.cfg and .bzrignore, thanks Jacob Kaplan-Moss. + + 0.17 + ---- + + - Added an option to specify a log file for output redirection from + the WSGI script. Thanks to Guido Wesdorp for the patch. + + 0.16 + ---- + + - Subversion aliases are now supported (something like + svn+mystuff://myjunk). Thanks to Remco for the patch. + + 0.15.2 + ------ + + - Update to move pth-files finder from the __init__ method to the + install method so it runs in buildout-order, else it looks for pth + files in dirs that may not yet exist. Thanks to Chris Shenton for + the update to his original patch. + + 0.15.1 + ------ + + - Update to make the previously added pth-files option better + documented. + + 0.15 + ---- + + - Added "pth-files" option to add libraries to extra-paths from + site .pth files. Thanks to Chris Shenton for the patch. + + 0.14 + ---- + + - The recipe now supports creating a FCGI script. Thanks to Jannis + Leidel for the patch. + + - When downloading a Django recipe for the first time the recipe now + properly reports the url it is downloading from. + + 0.13 + ---- + + - Specifying a user name within a subversion url now works. The code + that determined the revision has been updated. This fixes issue + #274004. Thanks to Remco for the patch. + + - Updated the template for creating new projects. It now uses the + current admin system when generating it's `urls.py` file. This fixes + issue #276255. Thanks to Roland for the patch. + + 0.12.1 + ------ + + - Re-upload since CHANGES.txt was missing from the release + + 0.12 + ---- + + - The recipe no longer executes subversion to determine whether the + versions is to be downloaded using subversion. This fixes issue + #271145. Thanks to Kapil Thangavelu for the patch. + + - Changed the `pythonpath` option to `extra-paths`. This makes the + recipe more consistent with other recipes (see issue #270908). + + 0.11 + ---- + + - Another go at fixing the updating problem (#250811) by making sure + the update method is always called. It would not be called in the + previous version since the recipe wrote a random secret (if it + wasn't specified) to the options for use with a template. Buildout + saw this as a change in options and therefore always decided to + un-install & install. + + - When both projectegg and wsgi=True are specified, the generated wsgi + file did not have the correct settings file in it. This has been + fixed with a patch from Dan Fairs. + + - The recipe now has logging. All print statements have been replaced + and a few extra logging calls have been added. This makes the recipe + more informative about long running tasks. Thanks erny for the patch + from issue #260628. + + 0.10 + ---- + + - The recipe no longer expects the top level directory name in a + release tarball to be consistent with the version number. This fixes + issue #260097. Thanks to erny for reporting this issue and + suggesting a solution. + + - Revision pinns for the svn checkout now stay pinned when re-running + the buildout. This fixes issue #250811. Thanks to Remco for + reporting this. + + - Added an option to specify an egg to use as the project. This + disables the code which creates the basic project structure. Thanks + to Dan Fairs for the patch from issue #252647. + + 0.9.1 + ----- + + - Fixed the previous release which was broken due to a missing + manifest file + + 0.9 + --- + + - The settings option is fixed so that it supports arbitrary depth + settings paths (example; `conf.customer.development`). + + - The version argument now excepts a full svn url as well. You can use + this to get a branch or fix any url to a specific revision with the + standard svn @ syntax + + - The wsgi script is no longer made executable and readable only by + the user who ran buildout. This avoids problems with deployment. + +Platform: UNKNOWN +Classifier: Framework :: Buildout +Classifier: Framework :: Django +Classifier: Topic :: Software Development :: Build Tools +Classifier: Development Status :: 5 - Production/Stable +Classifier: License :: OSI Approved :: BSD License diff --git a/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/SOURCES.txt b/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/SOURCES.txt new file mode 100644 index 0000000..ded8ede --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/SOURCES.txt @@ -0,0 +1,25 @@ +.bzrignore +CHANGES.txt +README.txt +bootstrap.py +buildout.cfg +fabfile +setup.cfg +setup.py +src/djangorecipe/__init__.py +src/djangorecipe/fcgi.py +src/djangorecipe/manage.py +src/djangorecipe/recipe.py +src/djangorecipe/test.py +src/djangorecipe/tests.py +src/djangorecipe/wsgi.py +src/djangorecipe.egg-info/PKG-INFO +src/djangorecipe.egg-info/SOURCES.txt +src/djangorecipe.egg-info/dependency_links.txt +src/djangorecipe.egg-info/entry_points.txt +src/djangorecipe.egg-info/not-zip-safe +src/djangorecipe.egg-info/requires.txt +src/djangorecipe.egg-info/top_level.txt +src/djangorecipe/testing/django/__init__.py +src/djangorecipe/testing/django/core/__init__.py +src/djangorecipe/testing/django/core/management.py
\ No newline at end of file diff --git a/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/dependency_links.txt b/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/entry_points.txt b/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/entry_points.txt new file mode 100644 index 0000000..844004d --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/entry_points.txt @@ -0,0 +1,5 @@ + + # -*- Entry points: -*- + [zc.buildout] + default = djangorecipe.recipe:Recipe +
\ No newline at end of file diff --git a/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/not-zip-safe b/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/not-zip-safe new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/not-zip-safe @@ -0,0 +1 @@ + diff --git a/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/requires.txt b/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/requires.txt new file mode 100644 index 0000000..0cf9b27 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/requires.txt @@ -0,0 +1,2 @@ +zc.buildout +zc.recipe.egg
\ No newline at end of file diff --git a/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/top_level.txt b/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/top_level.txt new file mode 100644 index 0000000..7d37670 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/top_level.txt @@ -0,0 +1 @@ +djangorecipe diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/__init__.py b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/__init__.py diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/__init__.pyo b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/__init__.pyo Binary files differnew file mode 100644 index 0000000..7898e21 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/__init__.pyo diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/fcgi.py b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/fcgi.py new file mode 100644 index 0000000..17a793e --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/fcgi.py @@ -0,0 +1,29 @@ +from django.core import management + +def main(settings_file, logfile=None): + try: + mod = __import__(settings_file) + components = settings_file.split('.') + for comp in components[1:]: + mod = getattr(mod, comp) + + except ImportError, e: + import sys + sys.stderr.write("Error loading the settings module '%s': %s" + % (settings_file, e)) + sys.exit(1) + + # Setup settings + management.setup_environ(mod) + + from django.conf import settings + + options = getattr(settings, 'FCGI_OPTIONS', {}) + if logfile: + options['outlog'] = logfile + options['errlog'] = logfile + + from django.core.servers.fastcgi import runfastcgi + + # Run FASTCGI handler + runfastcgi(**options) diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/fcgi.pyo b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/fcgi.pyo Binary files differnew file mode 100644 index 0000000..62633ea --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/fcgi.pyo diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/manage.py b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/manage.py new file mode 100644 index 0000000..6a61411 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/manage.py @@ -0,0 +1,16 @@ +from django.core import management + +def main(settings_file): + try: + mod = __import__(settings_file) + components = settings_file.split('.') + for comp in components[1:]: + mod = getattr(mod, comp) + + except ImportError, e: + import sys + sys.stderr.write("Error loading the settings module '%s': %s" + % (settings_file, e)) + return sys.exit(1) + + management.execute_manager(mod) diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/manage.pyo b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/manage.pyo Binary files differnew file mode 100644 index 0000000..d483aac --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/manage.pyo diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/recipe.py b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/recipe.py new file mode 100644 index 0000000..2282513 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/recipe.py @@ -0,0 +1,466 @@ +from random import choice +import os +import subprocess +import urllib2 +import shutil +import logging +import re + +from zc.buildout import UserError +import zc.recipe.egg +import setuptools + +script_template = { + 'wsgi': ''' + +%(relative_paths_setup)s +import sys +sys.path[0:0] = [ + %(path)s, + ] +%(initialization)s +import %(module_name)s + +application = %(module_name)s.%(attrs)s(%(arguments)s) +''', + 'fcgi': ''' + +%(relative_paths_setup)s +import sys +sys.path[0:0] = [ + %(path)s, + ] +%(initialization)s +import %(module_name)s + +%(module_name)s.%(attrs)s(%(arguments)s) +''' +} + + +settings_template = ''' +import os + +ADMINS = ( + # ('Your Name', 'your_email@domain.com'), +) + +MANAGERS = ADMINS + +DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. +DATABASE_NAME = '%(project)s.db' +DATABASE_USER = '' # Not used with sqlite3. +DATABASE_PASSWORD = '' # Not used with sqlite3. +DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3. +DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. + +TIME_ZONE = 'America/Chicago' + +LANGUAGE_CODE = 'en-us' + +# Absolute path to the directory that holds media. +# Example: "/home/media/media.lawrence.com/" +MEDIA_ROOT = %(media_root)s + +# URL that handles the media served from MEDIA_ROOT. Make sure to use a +# trailing slash if there is a path component (optional in other cases). +# Examples: "http://media.lawrence.com", "http://example.com/media/" +MEDIA_URL = '/media/' + +# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a +# trailing slash. +# Examples: "http://foo.com/media/", "/media/". +ADMIN_MEDIA_PREFIX = '/admin_media/' + +# Don't share this with anybody. +SECRET_KEY = '%(secret)s' + +MIDDLEWARE_CLASSES = ( + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.middleware.doc.XViewMiddleware', +) + +ROOT_URLCONF = '%(urlconf)s' + + +INSTALLED_APPS = ( + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.admin', +) + +TEMPLATE_LOADERS = ( + 'django.template.loaders.filesystem.load_template_source', + 'django.template.loaders.app_directories.load_template_source', +) + +TEMPLATE_DIRS = ( + os.path.join(os.path.dirname(__file__), "templates"), +) + + +''' + +production_settings = ''' +from %(project)s.settings import * +''' + +development_settings = ''' +from %(project)s.settings import * +DEBUG=True +TEMPLATE_DEBUG=DEBUG +''' + +urls_template = ''' +from django.conf.urls.defaults import patterns, include, handler500 +from django.conf import settings +from django.contrib import admin +admin.autodiscover() + +handler500 # Pyflakes + +urlpatterns = patterns( + '', + (r'^admin/(.*)', admin.site.root), + (r'^accounts/login/$', 'django.contrib.auth.views.login'), +) + +if settings.DEBUG: + urlpatterns += patterns('', + (r'^media/(?P<path>.*)$', 'django.views.static.serve', + {'document_root': settings.MEDIA_ROOT}), + ) +''' + +class Recipe(object): + def __init__(self, buildout, name, options): + self.log = logging.getLogger(name) + self.egg = zc.recipe.egg.Egg(buildout, options['recipe'], options) + + self.buildout, self.name, self.options = buildout, name, options + options['location'] = os.path.join( + buildout['buildout']['parts-directory'], name) + options['bin-directory'] = buildout['buildout']['bin-directory'] + + options.setdefault('project', 'project') + options.setdefault('settings', 'development') + + options.setdefault('urlconf', options['project'] + '.urls') + options.setdefault( + 'media_root', + "os.path.join(os.path.dirname(__file__), 'media')") + # Set this so the rest of the recipe can expect the values to be + # there. We need to make sure that both pythonpath and extra-paths are + # set for BBB. + if 'extra-paths' in options: + options['pythonpath'] = options['extra-paths'] + else: + options.setdefault('extra-paths', options.get('pythonpath', '')) + + # Usefull when using archived versions + buildout['buildout'].setdefault( + 'download-cache', + os.path.join(buildout['buildout']['directory'], + 'downloads')) + + # mod_wsgi support script + options.setdefault('wsgi', 'false') + options.setdefault('fcgi', 'false') + options.setdefault('wsgilog', '') + options.setdefault('logfile', '') + + # only try to download stuff if we aren't asked to install from cache + self.install_from_cache = self.buildout['buildout'].get( + 'install-from-cache', '').strip() == 'true' + + + def install(self): + location = self.options['location'] + base_dir = self.buildout['buildout']['directory'] + + project_dir = os.path.join(base_dir, self.options['project']) + + download_dir = self.buildout['buildout']['download-cache'] + if not os.path.exists(download_dir): + os.mkdir(download_dir) + + version = self.options['version'] + # Remove a pre-existing installation if it is there + if os.path.exists(location): + shutil.rmtree(location) + + if self.is_svn_url(version): + self.install_svn_version(version, download_dir, location, + self.install_from_cache) + else: + tarball = self.get_release(version, download_dir) + # Extract and put the dir in its proper place + self.install_release(version, download_dir, tarball, location) + + self.options['setup'] = location + development = zc.recipe.egg.Develop(self.buildout, + self.options['recipe'], + self.options) + development.install() + del self.options['setup'] + + extra_paths = self.get_extra_paths() + requirements, ws = self.egg.working_set(['djangorecipe']) + + script_paths = [] + + # Create the Django management script + script_paths.extend(self.create_manage_script(extra_paths, ws)) + + # Create the test runner + script_paths.extend(self.create_test_runner(extra_paths, ws)) + + # Make the wsgi and fastcgi scripts if enabled + script_paths.extend(self.make_scripts(extra_paths, ws)) + + # Create default settings if we haven't got a project + # egg specified, and if it doesn't already exist + if not self.options.get('projectegg'): + if not os.path.exists(project_dir): + self.create_project(project_dir) + else: + self.log.info( + 'Skipping creating of project: %(project)s since ' + 'it exists' % self.options) + + return script_paths + [location] + + def install_svn_version(self, version, download_dir, location, + install_from_cache): + svn_url = self.version_to_svn(version) + download_location = os.path.join( + download_dir, 'django-' + + self.version_to_download_suffix(version)) + if not install_from_cache: + if os.path.exists(download_location): + if self.svn_update(download_location, version): + raise UserError( + "Failed to update Django; %s. " + "Please check your internet connection." % ( + download_location)) + else: + self.log.info("Checking out Django from svn: %s" % svn_url) + cmd = 'svn co %s %s' % (svn_url, download_location) + if not self.buildout['buildout'].get('verbosity'): + cmd += ' -q' + if self.command(cmd): + raise UserError("Failed to checkout Django. " + "Please check your internet connection.") + else: + self.log.info("Installing Django from cache: " + download_location) + + shutil.copytree(download_location, location) + + + def install_release(self, version, download_dir, tarball, destination): + extraction_dir = os.path.join(download_dir, 'django-archive') + setuptools.archive_util.unpack_archive(tarball, extraction_dir) + # Lookup the resulting extraction dir instead of guessing it + # (Django releases have a tendency not to be consistend here) + untarred_dir = os.path.join(extraction_dir, + os.listdir(extraction_dir)[0]) + shutil.move(untarred_dir, destination) + shutil.rmtree(extraction_dir) + + def get_release(self, version, download_dir): + tarball = os.path.join(download_dir, 'django-%s.tar.gz' % version) + + # Only download when we don't yet have an archive + if not os.path.exists(tarball): + download_url = 'http://www.djangoproject.com/download/%s/tarball/' + self.log.info("Downloading Django from: %s" % ( + download_url % version)) + + tarball_f = open(tarball, 'wb') + f = urllib2.urlopen(download_url % version) + tarball_f.write(f.read()) + tarball_f.close() + f.close() + return tarball + + def create_manage_script(self, extra_paths, ws): + project = self.options.get('projectegg', self.options['project']) + return zc.buildout.easy_install.scripts( + [(self.options.get('control-script', self.name), + 'djangorecipe.manage', 'main')], + ws, self.options['executable'], self.options['bin-directory'], + extra_paths = extra_paths, + arguments= "'%s.%s'" % (project, + self.options['settings'])) + + + + def create_test_runner(self, extra_paths, working_set): + apps = self.options.get('test', '').split() + # Only create the testrunner if the user requests it + if apps: + return zc.buildout.easy_install.scripts( + [(self.options.get('testrunner', 'test'), + 'djangorecipe.test', 'main')], + working_set, self.options['executable'], + self.options['bin-directory'], + extra_paths = extra_paths, + arguments= "'%s.%s', %s" % ( + self.options['project'], + self.options['settings'], + ', '.join(["'%s'" % app for app in apps]))) + else: + return [] + + + def create_project(self, project_dir): + os.makedirs(project_dir) + + template_vars = {'secret': self.generate_secret()} + template_vars.update(self.options) + + self.create_file( + os.path.join(project_dir, 'development.py'), + development_settings, template_vars) + + self.create_file( + os.path.join(project_dir, 'production.py'), + production_settings, template_vars) + + self.create_file( + os.path.join(project_dir, 'urls.py'), + urls_template, template_vars) + + self.create_file( + os.path.join(project_dir, 'settings.py'), + settings_template, template_vars) + + # Create the media and templates directories for our + # project + os.mkdir(os.path.join(project_dir, 'media')) + os.mkdir(os.path.join(project_dir, 'templates')) + + # Make the settings dir a Python package so that Django + # can load the settings from it. It will act like the + # project dir. + open(os.path.join(project_dir, '__init__.py'), 'w').close() + + def make_scripts(self, extra_paths, ws): + scripts = [] + _script_template = zc.buildout.easy_install.script_template + for protocol in ('wsgi', 'fcgi'): + zc.buildout.easy_install.script_template = \ + zc.buildout.easy_install.script_header + \ + script_template[protocol] + if self.options.get(protocol, '').lower() == 'true': + project = self.options.get('projectegg', + self.options['project']) + scripts.extend( + zc.buildout.easy_install.scripts( + [('%s.%s' % (self.options.get('control-script', + self.name), + protocol), + 'djangorecipe.%s' % protocol, 'main')], + ws, + self.options['executable'], + self.options['bin-directory'], + extra_paths=extra_paths, + arguments= "'%s.%s', logfile='%s'" % ( + project, self.options['settings'], + self.options.get('logfile')))) + zc.buildout.easy_install.script_template = _script_template + return scripts + + def is_svn_url(self, version): + # Search if there is http/https/svn or svn+[a tunnel identifier] in the + # url or if the trunk marker is used, all indicating the use of svn + svn_version_search = re.compile( + r'^(http|https|svn|svn\+[a-zA-Z-_]+)://|^(trunk)$').search(version) + return svn_version_search is not None + + def version_to_svn(self, version): + if version == 'trunk': + return 'http://code.djangoproject.com/svn/django/trunk/' + else: + return version + + def version_to_download_suffix(self, version): + if version == 'trunk': + return 'svn' + return [p for p in version.split('/') if p][-1] + + def svn_update(self, path, version): + command = 'svn up' + revision_search = re.compile(r'@([0-9]*)$').search( + self.options['version']) + + if revision_search is not None: + command += ' -r ' + revision_search.group(1) + self.log.info("Updating Django from svn") + if not self.buildout['buildout'].get('verbosity'): + command += ' -q' + return self.command(command, cwd=path) + + def get_extra_paths(self): + extra_paths = [self.options['location'], + self.buildout['buildout']['directory'] + ] + + # Add libraries found by a site .pth files to our extra-paths. + if 'pth-files' in self.options: + import site + for pth_file in self.options['pth-files'].splitlines(): + pth_libs = site.addsitedir(pth_file, set()) + if not pth_libs: + self.log.warning( + "No site *.pth libraries found for pth_file=%s" % ( + pth_file,)) + else: + self.log.info("Adding *.pth libraries=%s" % pth_libs) + self.options['extra-paths'] += '\n' + '\n'.join(pth_libs) + + pythonpath = [p.replace('/', os.path.sep) for p in + self.options['extra-paths'].splitlines() if p.strip()] + + extra_paths.extend(pythonpath) + return extra_paths + + def update(self): + newest = self.buildout['buildout'].get('newest') != 'false' + if newest and not self.install_from_cache and \ + self.is_svn_url(self.options['version']): + self.svn_update(self.options['location'], self.options['version']) + + extra_paths = self.get_extra_paths() + requirements, ws = self.egg.working_set(['djangorecipe']) + # Create the Django management script + self.create_manage_script(extra_paths, ws) + + # Create the test runner + self.create_test_runner(extra_paths, ws) + + # Make the wsgi and fastcgi scripts if enabled + self.make_scripts(extra_paths, ws) + + def command(self, cmd, **kwargs): + output = subprocess.PIPE + if self.buildout['buildout'].get('verbosity'): + output = None + command = subprocess.Popen( + cmd, shell=True, stdout=output, **kwargs) + return command.wait() + + def create_file(self, file, template, options): + if os.path.exists(file): + return + + f = open(file, 'w') + f.write(template % options) + f.close() + + def generate_secret(self): + chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)' + return ''.join([choice(chars) for i in range(50)]) diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/recipe.pyo b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/recipe.pyo Binary files differnew file mode 100644 index 0000000..a73b499 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/recipe.pyo diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/test.py b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/test.py new file mode 100644 index 0000000..8cad491 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/test.py @@ -0,0 +1,16 @@ +from django.core import management + +def main(settings_file, *apps): + argv = ['test', 'test'] + list(apps) + try: + settings = __import__(settings_file) + components = settings_file.split('.') + for comp in components[1:]: + settings = getattr(settings, comp) + except ImportError, e: + import sys + sys.stderr.write("Error loading the settings module '%s': %s" + % (settings_file, e)) + return sys.exit(1) + + management.execute_manager(settings, argv=argv) diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/test.pyo b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/test.pyo Binary files differnew file mode 100644 index 0000000..2d4d58d --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/test.pyo diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/tests.py b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/tests.py new file mode 100644 index 0000000..8d83ad7 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/tests.py @@ -0,0 +1,790 @@ +import unittest +import tempfile +import os +import sys +import shutil + +import mock +from zc.buildout import UserError +from zc.recipe.egg.egg import Scripts as ZCRecipeEggScripts + +from djangorecipe.recipe import Recipe + +# Add the testing dir to the Python path so we can use a fake Django +# install. This needs to be done so that we can use this as a base for +# mock's with some of the tests. +sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'testing')) + +# Now that we have a fake Django on the path we can import the +# scripts. These are depenent on a Django install, hence the fake one. +from djangorecipe import test +from djangorecipe import manage + + +class TestRecipe(unittest.TestCase): + + def setUp(self): + # Create a directory for our buildout files created by the recipe + self.buildout_dir = tempfile.mkdtemp('djangorecipe') + + self.bin_dir = os.path.join(self.buildout_dir, 'bin') + self.develop_eggs_dir = os.path.join(self.buildout_dir, + 'develop-eggs') + self.eggs_dir = os.path.join(self.buildout_dir, 'eggs') + self.parts_dir = os.path.join(self.buildout_dir, 'parts') + + # We need to create the bin dir since the recipe should be able to expect it exists + os.mkdir(self.bin_dir) + + self.recipe = Recipe({'buildout': {'eggs-directory': self.eggs_dir, + 'develop-eggs-directory': self.develop_eggs_dir, + 'python': 'python-version', + 'bin-directory': self.bin_dir, + 'parts-directory': self.parts_dir, + 'directory': self.buildout_dir, + }, + 'python-version': {'executable': sys.executable}}, + 'django', + {'recipe': 'djangorecipe', + 'version': 'trunk'}) + + def tearDown(self): + # Remove our test dir + shutil.rmtree(self.buildout_dir) + + def test_consistent_options(self): + # Buildout is pretty clever in detecting changing options. If + # the recipe modifies it's options during initialisation it + # will store this to determine wheter it needs to update or do + # a uninstall & install. We need to make sure that we normally + # do not trigger this. That means running the recipe with the + # same options should give us the same results. + self.assertEqual(*[ + Recipe({'buildout': {'eggs-directory': self.eggs_dir, + 'develop-eggs-directory': self.develop_eggs_dir, + 'python': 'python-version', + 'bin-directory': self.bin_dir, + 'parts-directory': self.parts_dir, + 'directory': self.buildout_dir, + }, + 'python-version': {'executable': sys.executable}}, + 'django', + {'recipe': 'djangorecipe', + 'version': 'trunk'}).options.copy() for i in range(2)]) + + def test_svn_url(self): + # Make sure that only a few specific type of url's are + # considered svn url's + + # This is a plain release version so it should indicate it is + # not a svn url + self.failIf(self.recipe.is_svn_url('0.96.2')) + # The next line specifies a proper link with the trunk + self.assert_(self.recipe.is_svn_url('trunk')) + # A url looking like trunk should also fail + self.failIf(self.recipe.is_svn_url('trunka')) + # A full svn url including version should work + self.assert_(self.recipe.is_svn_url( + 'http://code.djangoproject.com/svn/django/branches/newforms-admin@7833')) + # HTTPS should work too + self.assert_(self.recipe.is_svn_url( + 'https://code.djangoproject.com/svn/django/branches/newforms-admin@7833')) + # Svn+ssh should work + self.assert_(self.recipe.is_svn_url( + 'svn+ssh://myserver/newforms-admin@7833')) + # Svn protocol through any custom tunnel defined in ~/.subversion/config should work + self.assert_(self.recipe.is_svn_url( + 'svn+MY_Custom-tunnel://myserver/newforms-admin@7833')) + # Using a non existent protocol should not be a svn url? + self.failIf(self.recipe.is_svn_url( + 'unknown://myserver/newforms-admin@7833')) + + def test_command(self): + # The command method is a wrapper for subprocess which excutes + # a command and return's it's status code. We will demonstrate + # this with a simple test of running `dir`. + self.failIf(self.recipe.command('echo')) + # Executing a non existing command should return an error code + self.assert_(self.recipe.command('spamspamspameggs')) + + @mock.patch('subprocess', 'Popen') + def test_command_verbose_mode(self, popen): + # When buildout is put into verbose mode the command methode + # should stop capturing the ouput of it's commands. + popen.return_value = mock.Mock() + self.recipe.buildout['buildout']['verbosity'] = 'verbose' + self.recipe.command('silly-command') + self.assertEqual( + popen.call_args, + (('silly-command',), {'shell': True, 'stdout': None})) + + def test_create_file(self): + # The create file helper should create a file at a certain + # location unless it already exists. We will need a + # non-existing file first. + f, name = tempfile.mkstemp() + # To show the function in action we need to delete the file + # before testing. + os.remove(name) + # The method accepts a template argument which it will use + # with the options argument for string substitution. + self.recipe.create_file(name, 'Spam %s', 'eggs') + # Let's check the contents of the file + self.assertEqual(open(name).read(), 'Spam eggs') + # If we try to write it again it will just ignore our request + self.recipe.create_file(name, 'Spam spam spam %s', 'eggs') + # The content of the file should therefore be the same + self.assertEqual(open(name).read(), 'Spam eggs') + # Now remove our temp file + os.remove(name) + + def test_generate_secret(self): + # To create a basic skeleton the recipe also generates a + # random secret for the settings file. Since it should very + # unlikely that it will generate the same key a few times in a + # row we will test it with letting it generate a few keys. + self.assert_(len(set( + [self.recipe.generate_secret() for i in xrange(10)])) > 1) + + def test_version_to_svn(self): + # Version specification that lead to a svn repository can be + # specified in different ways. Just specifying `trunk` should + # be enough to get the full url to the Django trunk. + self.assertEqual(self.recipe.version_to_svn('trunk'), + 'http://code.djangoproject.com/svn/django/trunk/') + # Any other specification should lead to the url it is given + self.assertEqual(self.recipe.version_to_svn('svn://somehost/trunk'), + 'svn://somehost/trunk') + + def test_version_to_download_suffic(self): + # To create standard names for the download directory a method + # is provided which converts a version to a dir suffix. A + # simple pointer to trunk should return svn. + self.assertEqual(self.recipe.version_to_download_suffix('trunk'), + 'svn') + # Any other url should return the last path component. This + # works out nicely for branches or version pinned url's. + self.assertEqual(self.recipe.version_to_download_suffix( + 'http://monty/branches/python'), 'python') + + def test_make_protocol_scripts(self): + # To ease deployment a WSGI script can be generated. The + # script adds any paths from the `extra_paths` option to the + # Python path. + self.recipe.options['wsgi'] = 'true' + self.recipe.options['fcgi'] = 'true' + self.recipe.make_scripts([], []) + # This should have created a script in the bin dir + wsgi_script = os.path.join(self.bin_dir, 'django.wsgi') + self.assert_(os.path.exists(wsgi_script)) + # The contents should list our paths + contents = open(wsgi_script).read() + # It should also have a reference to our settings module + self.assert_('project.development' in contents) + # and a line which set's up the WSGI app + self.assert_("application = " + "djangorecipe.wsgi.main('project.development', logfile='')" + in contents) + self.assert_("class logger(object)" not in contents) + + # Another deployment options is FCGI. The recipe supports an option to + # automatically create the required script. + fcgi_script = os.path.join(self.bin_dir, 'django.fcgi') + self.assert_(os.path.exists(fcgi_script)) + # The contents should list our paths + contents = open(fcgi_script).read() + # It should also have a reference to our settings module + self.assert_('project.development' in contents) + # and a line which set's up the WSGI app + self.assert_("djangorecipe.fcgi.main('project.development', logfile='')" + in contents) + self.assert_("class logger(object)" not in contents) + + self.recipe.options['logfile'] = '/foo' + self.recipe.make_scripts([], []) + wsgi_script = os.path.join(self.bin_dir, 'django.wsgi') + contents = open(wsgi_script).read() + self.assert_("logfile='/foo'" in contents) + + self.recipe.options['logfile'] = '/foo' + self.recipe.make_scripts([], []) + fcgi_script = os.path.join(self.bin_dir, 'django.fcgi') + contents = open(fcgi_script).read() + self.assert_("logfile='/foo'" in contents) + + @mock.patch('zc.buildout.easy_install', 'scripts') + def test_make_protocol_scripts_return_value(self, scripts): + # The return value of make scripts lists the generated scripts. + self.recipe.options['wsgi'] = 'true' + self.recipe.options['fcgi'] = 'true' + scripts.return_value = ['some-path'] + self.assertEqual(self.recipe.make_scripts([], []), + ['some-path', 'some-path']) + + + + def test_create_project(self): + # If a project does not exist already the recipe will create + # one. + project_dir = os.path.join(self.buildout_dir, 'project') + self.recipe.create_project(project_dir) + # This should have create a project directory + self.assert_(os.path.exists(project_dir)) + # With this directory we should have __init__.py to make it a + # package + self.assert_( + os.path.exists(os.path.join(project_dir, '__init__.py'))) + # There should also be a urls.py + self.assert_( + os.path.exists(os.path.join(project_dir, 'urls.py'))) + # To make it easier to start using this project both a media + # and a templates folder are created + self.assert_( + os.path.exists(os.path.join(project_dir, 'media'))) + self.assert_( + os.path.exists(os.path.join(project_dir, 'templates'))) + # The project is ready to go since the recipe has generated a + # base settings, development and production file + for f in ('settings.py', 'development.py', 'production.py'): + self.assert_( + os.path.exists(os.path.join(project_dir, f))) + + def test_create_test_runner(self): + # An executable script can be generated which will make it + # possible to execute the Django test runner. This options + # only works if we specify one or apps to test. + testrunner = os.path.join(self.bin_dir, 'test') + + # This first argument sets extra_paths, we will use this to + # make sure the script can find this recipe + recipe_dir = os.path.abspath( + os.path.join(os.path.dirname(__file__), '..')) + + # First we will show it does nothing by default + self.recipe.create_test_runner([recipe_dir], []) + self.failIf(os.path.exists(testrunner)) + + # When we specify an app to test it should create the the + # testrunner + self.recipe.options['test'] = 'knight' + self.recipe.create_test_runner([recipe_dir], []) + self.assert_(os.path.exists(testrunner)) + + def test_create_manage_script(self): + # This buildout recipe creates a alternative for the standard + # manage.py script. It has all the same functionality as the + # original one but it sits in the bin dir instead of within + # the project. + manage = os.path.join(self.bin_dir, 'django') + self.recipe.create_manage_script([], []) + self.assert_(os.path.exists(manage)) + + def test_create_manage_script_projectegg(self): + # When a projectegg is specified, then the egg specified + # should get used as the project file. + manage = os.path.join(self.bin_dir, 'django') + self.recipe.options['projectegg'] = 'spameggs' + self.recipe.create_manage_script([], []) + self.assert_(os.path.exists(manage)) + # Check that we have 'spameggs' as the project + self.assert_("djangorecipe.manage.main('spameggs.development')" + in open(manage).read()) + + @mock.patch('shutil', 'rmtree') + @mock.patch('os.path', 'exists') + @mock.patch('urllib', 'urlretrieve') + @mock.patch('shutil', 'copytree') + @mock.patch(ZCRecipeEggScripts, 'working_set') + @mock.patch('zc.buildout.easy_install', 'scripts') + @mock.patch(Recipe, 'install_release') + @mock.patch(Recipe, 'create_manage_script') + @mock.patch(Recipe, 'create_test_runner') + @mock.patch('zc.recipe.egg', 'Develop') + def test_fulfills_django_dependency(self, rmtree, path_exists, + urlretrieve, copytree, working_set, scripts, install_release, + manage, testrunner, develop): + # Test for https://bugs.launchpad.net/djangorecipe/+bug/397864 + # djangorecipe should always fulfil the 'Django' requirement. + self.recipe.options['version'] = '1.0' + path_exists.return_value = True + working_set.return_value = (None, []) + manage.return_value = [] + scripts.return_value = [] + testrunner.return_value = [] + develop_install = mock.Mock() + develop.return_value = develop_install + self.recipe.install() + + # We should see that Django was added as a develop egg. + options = develop.call_args[0][2] + self.assertEqual(options['location'], os.path.join(self.parts_dir, 'django')) + + # Check that the install() method for the develop egg was called with no args + first_method_name, args, kwargs = develop_install.method_calls[0] + self.assertEqual('install', first_method_name) + self.assertEqual(0, len(args)) + self.assertEqual(0, len(kwargs)) + + @mock.patch('shutil', 'rmtree') + @mock.patch('os.path', 'exists') + @mock.patch('urllib', 'urlretrieve') + @mock.patch('shutil', 'copytree') + @mock.patch(ZCRecipeEggScripts, 'working_set') + @mock.patch('zc.buildout.easy_install', 'scripts') + @mock.patch(Recipe, 'install_release') + @mock.patch(Recipe, 'create_manage_script') + @mock.patch(Recipe, 'create_test_runner') + @mock.patch('zc.recipe.egg', 'Develop') + def test_extra_paths(self, rmtree, path_exists, urlretrieve, + copytree, working_set, scripts, + install_release, manage, testrunner, + develop): + # The recipe allows extra-paths to be specified. It uses these to + # extend the Python path within it's generated scripts. + self.recipe.options['version'] = '1.0' + self.recipe.options['extra-paths'] = 'somepackage\nanotherpackage' + path_exists.return_value = True + working_set.return_value = (None, []) + manage.return_value = [] + scripts.return_value = [] + testrunner.return_value = [] + develop.return_value = mock.Mock() + self.recipe.install() + self.assertEqual(manage.call_args[0][0][-2:], + ['somepackage', 'anotherpackage']) + + @mock.patch('shutil', 'rmtree') + @mock.patch('os.path', 'exists') + @mock.patch('urllib', 'urlretrieve') + @mock.patch('shutil', 'copytree') + @mock.patch(ZCRecipeEggScripts, 'working_set') + @mock.patch('zc.buildout.easy_install', 'scripts') + @mock.patch(Recipe, 'install_release') + @mock.patch(Recipe, 'create_manage_script') + @mock.patch(Recipe, 'create_test_runner') + @mock.patch('site', 'addsitedir') + @mock.patch('zc.recipe.egg', 'Develop') + def test_pth_files(self, rmtree, path_exists, urlretrieve, + copytree, working_set, scripts, + install_release, manage, testrunner, addsitedir, + develop): + # When a pth-files option is set the recipe will use that to add more + # paths to extra-paths. + self.recipe.options['version'] = '1.0' + path_exists.return_value = True + working_set.return_value = (None, []) + scripts.return_value = [] + manage.return_value = [] + testrunner.return_value = [] + develop.return_value = mock.Mock() + + # The mock values needed to demonstrate the pth-files option. + addsitedir.return_value = ['extra', 'dirs'] + self.recipe.options['pth-files'] = 'somedir' + + self.recipe.install() + self.assertEqual(addsitedir.call_args, (('somedir', set([])), {})) + # The extra-paths option has been extended. + self.assertEqual(self.recipe.options['extra-paths'], '\nextra\ndirs') + + def test_create_wsgi_script_projectegg(self): + # When a projectegg is specified, then the egg specified + # should get used as the project in the wsgi script. + wsgi = os.path.join(self.bin_dir, 'django.wsgi') + recipe_dir = os.path.abspath( + os.path.join(os.path.dirname(__file__), '..')) + self.recipe.options['projectegg'] = 'spameggs' + self.recipe.options['wsgi'] = 'true' + self.recipe.make_scripts([recipe_dir], []) + self.assert_(os.path.exists(wsgi)) + # Check that we have 'spameggs' as the project + self.assert_('spameggs.development' in open(wsgi).read()) + + def test_settings_option(self): + # The settings option can be used to specify the settings file + # for Django to use. By default it uses `development`. + self.assertEqual(self.recipe.options['settings'], 'development') + # When we change it an generate a manage script it will use + # this var. + self.recipe.options['settings'] = 'spameggs' + self.recipe.create_manage_script([], []) + manage = os.path.join(self.bin_dir, 'django') + self.assert_("djangorecipe.manage.main('project.spameggs')" + in open(manage).read()) + + @mock.patch('urllib2', 'urlopen') + def test_get_release(self, mock): + # The get_release method fecthes a release tarball and + # extracts it. We have setup a mock so that it won't actually + # download the release. Let's call the code. + class FakeFile(object): + def read(self): + return 'Django tarball' + def close(self): + self.closed = True + + tmp = tempfile.mkdtemp() + filename = os.path.join(tmp, 'django-0.96.2.tar.gz') + mock.return_value = FakeFile() + try: + self.assertEqual( + self.recipe.get_release('0.96.2', tmp), + filename) + # It tried to download the release through our mock + mock.assert_called_with( + 'http://www.djangoproject.com/download/0.96.2/tarball/') + # The file should have been filled with the contents from the + # handle it got. + self.assertEqual(open(filename).read(), 'Django tarball') + finally: + shutil.rmtree(tmp) + + @mock.patch('setuptools.archive_util', 'unpack_archive') + @mock.patch('shutil', 'move') + @mock.patch('shutil', 'rmtree') + @mock.patch('os', 'listdir') + def test_install_release(self, unpack, move, rmtree, listdir): + # To install a release the recipe uses a specific method. We + # have have mocked all the calls which interact with the + # filesystem. + listdir.return_value = ('Django-0.96-2',) + self.recipe.install_release('0.96.2', 'downloads', + 'downloads/django-0.96.2.tar.gz', + 'parts/django') + # Let's see what the mock's have been called with + self.assertEqual(listdir.call_args, + (('downloads/django-archive',), {})) + self.assertEqual(unpack.call_args, + (('downloads/django-0.96.2.tar.gz', + 'downloads/django-archive'), {})) + self.assertEqual(move.call_args, + (('downloads/django-archive/Django-0.96-2', + 'parts/django'), {})) + self.assertEqual(rmtree.call_args, + (('downloads/django-archive',), {})) + + @mock.patch('shutil', 'copytree') + @mock.patch(Recipe, 'command') + def test_install_svn_version(self, copytree, command): + # Installation from svn is handled by a method. We have mocked + # the command method to avoid actual checkouts of Django. + self.recipe.install_svn_version('trunk', 'downloads', + 'parts/django', False) + # This should have tried to do a checkout of the Django trunk + self.assertEqual(command.call_args, + (('svn co http://code.djangoproject.com/svn/django/trunk/ downloads/django-svn -q',), {})) + # A copy command to the parts directory should also have been + # issued + self.assertEqual(copytree.call_args, + (('downloads/django-svn', 'parts/django'), {})) + + @mock.patch('shutil', 'copytree') + @mock.patch('os.path', 'exists') + @mock.patch(Recipe, 'command') + def test_install_and_update_svn_version(self, copytree, exists, command): + # When an checkout has been done of a svn based installation + # is already done the recipe should just update it. + exists.return_value = True + + self.recipe.install_svn_version('trunk', 'downloads', + 'parts/django', False) + self.assertEqual(exists.call_args, (('downloads/django-svn',), {})) + self.assertEqual(command.call_args, + (('svn up -q',), {'cwd': 'downloads/django-svn'})) + + @mock.patch(Recipe, 'command') + def test_install_broken_svn(self, command): + # When the checkout from svn fails during a svn build the + # installation method raises an error. We will simulate this + # failure by telling our mock what to do. + command.return_value = 1 + # The line above should indicate a failure (non-zero exit + # code) + self.assertRaises(UserError, self.recipe.install_svn_version, + 'trunk', 'downloads', 'parts/django', False) + + @mock.patch('shutil', 'copytree') + @mock.patch(Recipe, 'command') + def test_svn_install_from_cache(self, copytree, command): + # If the buildout is told to install from cache it will not do + # a checkout but instead an existing checkout + self.recipe.buildout['buildout']['install-from-cache'] = 'true' + # Now we can run the installation method + self.recipe.install_svn_version('trunk', 'downloads', + 'parts/django', True) + # This should not have called the recipe's command method + self.failIf(command.called) + # A copy from the cache to the destination should have been + # made + self.assertEqual(copytree.call_args, + (('downloads/django-svn', 'parts/django'), {})) + + @mock.patch('shutil', 'rmtree') + @mock.patch('os.path', 'exists') + @mock.patch('urllib', 'urlretrieve') + @mock.patch('shutil', 'copytree') + @mock.patch(ZCRecipeEggScripts, 'working_set') + @mock.patch('zc.buildout.easy_install', 'scripts') + @mock.patch(Recipe, 'install_release') + @mock.patch(Recipe, 'command') + def test_update_svn(self, rmtree, path_exists, urlretrieve, + copytree, working_set, scripts, + install_release, command): + path_exists.return_value = True + working_set.return_value = (None, []) + # When the recipe is asked to do an update and the version is + # a svn version it just does an update on the parts folder. + self.recipe.update() + self.assertEqual('svn up -q', command.call_args[0][0]) + # It changes the working directory so that the simple svn up + # command will work. + self.assertEqual(command.call_args[1].keys(), ['cwd']) + + @mock.patch('shutil', 'rmtree') + @mock.patch('os.path', 'exists') + @mock.patch('urllib', 'urlretrieve') + @mock.patch('shutil', 'copytree') + @mock.patch(ZCRecipeEggScripts, 'working_set') + @mock.patch('zc.buildout.easy_install', 'scripts') + @mock.patch(Recipe, 'install_release') + @mock.patch('subprocess', 'call') + def test_update_with_cache(self, rmtree, path_exists, urlretrieve, + copytree, working_set, scripts, + install_release, call_process): + path_exists.return_value = True + working_set.return_value = (None, []) + # When the recipe is asked to do an update whilst in install + # from cache mode it just ignores it + self.recipe.install_from_cache = True + self.recipe.update() + self.failIf(call_process.called) + + @mock.patch('shutil', 'rmtree') + @mock.patch('os.path', 'exists') + @mock.patch('urllib', 'urlretrieve') + @mock.patch('shutil', 'copytree') + @mock.patch(ZCRecipeEggScripts, 'working_set') + @mock.patch('zc.buildout.easy_install', 'scripts') + @mock.patch(Recipe, 'install_release') + @mock.patch('subprocess', 'call') + def test_update_with_newest_false(self, rmtree, path_exists, urlretrieve, + copytree, working_set, scripts, + install_release, call_process): + path_exists.return_value = True + working_set.return_value = (None, []) + # When the recipe is asked to do an update whilst in install + # from cache mode it just ignores it + self.recipe.buildout['buildout']['newest'] = 'false' + self.recipe.update() + self.assertFalse(call_process.called) + + @mock.patch('shutil', 'rmtree') + @mock.patch('os.path', 'exists') + @mock.patch('urllib', 'urlretrieve') + @mock.patch('shutil', 'copytree') + @mock.patch(ZCRecipeEggScripts, 'working_set') + @mock.patch('zc.buildout.easy_install', 'scripts') + @mock.patch(Recipe, 'install_release') + @mock.patch('zc.recipe.egg', 'Develop') + def test_clear_existing_django(self, rmtree, path_exists, urlretrieve, + copytree, working_set, scripts, + install_release, develop): + # When the recipe is executed and Django is already installed + # within parts it should remove it. We will mock the exists + # check to make it let the recipe think it has an existing + # Django install. + self.recipe.options['version'] = '1.0' + path_exists.return_value = True + working_set.return_value = (None, []) + scripts.return_value = [] + develop.return_value = mock.Mock() + self.recipe.install() + # This should have called remove tree + self.assert_(rmtree.called) + # We will assert that the last two compontents of the path + # passed to rmtree are the ones we wanted to delete. + self.assertEqual(rmtree.call_args[0][0].split('/')[-2:], + ['parts', 'django']) + + @mock.patch('shutil', 'rmtree') + @mock.patch('os.path', 'exists') + @mock.patch('urllib', 'urlretrieve') + @mock.patch('shutil', 'copytree') + @mock.patch(ZCRecipeEggScripts, 'working_set') + @mock.patch('zc.buildout.easy_install', 'scripts') + @mock.patch(Recipe, 'install_release') + @mock.patch(Recipe, 'command') + def test_update_pinned_svn_url(self, rmtree, path_exists, urlretrieve, + copytree, working_set, scripts, + install_release, command): + path_exists.return_value = True + working_set.return_value = (None, []) + # Make sure that updating a pinned version is updated + # accordingly. It must not switch to updating beyond it's + # requested revision. + # The recipe does this by checking for an @ sign in the url / + # version. + self.recipe.is_svn_url = lambda version: True + + self.recipe.options['version'] = 'http://testing/trunk@2531' + self.recipe.update() + self.assertEqual(command.call_args[0], ('svn up -r 2531 -q',)) + + @mock.patch('shutil', 'rmtree') + @mock.patch('os.path', 'exists') + @mock.patch('urllib', 'urlretrieve') + @mock.patch('shutil', 'copytree') + @mock.patch(ZCRecipeEggScripts, 'working_set') + @mock.patch('zc.buildout.easy_install', 'scripts') + @mock.patch(Recipe, 'install_release') + @mock.patch(Recipe, 'command') + def test_update_username_in_svn_url(self, rmtree, path_exists, urlretrieve, + copytree, working_set, scripts, + install_release, command): + path_exists.return_value = True + working_set.return_value = (None, []) + # Make sure that updating a version with a username + # in the URL works + self.recipe.is_svn_url = lambda version: True + + # First test with both a revision and a username in the url + self.recipe.options['version'] = 'http://user@testing/trunk@2531' + self.recipe.update() + self.assertEqual(command.call_args[0], ('svn up -r 2531 -q',)) + + # Now test with only the username + self.recipe.options['version'] = 'http://user@testing/trunk' + self.recipe.update() + self.assertEqual(command.call_args[0], ('svn up -q',)) + + def test_python_option(self): + # The python option makes it possible to specify a specific Python + # executable which is to be used for the generated scripts. + recipe = Recipe({'buildout': {'eggs-directory': self.eggs_dir, + 'develop-eggs-directory': self.develop_eggs_dir, + 'python': 'python-version', + 'bin-directory': self.bin_dir, + 'parts-directory': self.parts_dir, + 'directory': self.buildout_dir, + }, + 'python-version': {'executable': '/python4k'}}, + 'django', + {'recipe': 'djangorecipe', 'version': 'trunk', + 'wsgi': 'true'}) + recipe.make_scripts([], []) + # This should have created a script in the bin dir + wsgi_script = os.path.join(self.bin_dir, 'django.wsgi') + self.assertEqual(open(wsgi_script).readlines()[0], '#!/python4k\n') + # Changeing the option for only the part will change the used Python + # version. + recipe = Recipe({'buildout': {'eggs-directory': self.eggs_dir, + 'develop-eggs-directory': self.develop_eggs_dir, + 'python': 'python-version', + 'bin-directory': self.bin_dir, + 'parts-directory': self.parts_dir, + 'directory': self.buildout_dir, + }, + 'python-version': {'executable': '/python4k'}, + 'py5k': {'executable': '/python5k'}}, + 'django', + {'recipe': 'djangorecipe', 'version': 'trunk', + 'python': 'py5k', 'wsgi': 'true'}) + recipe.make_scripts([], []) + self.assertEqual(open(wsgi_script).readlines()[0], '#!/python5k\n') + +class ScriptTestCase(unittest.TestCase): + + def setUp(self): + # We will also need to fake the settings file's module + self.settings = mock.sentinel.Settings + sys.modules['cheeseshop'] = mock.sentinel.CheeseShop + sys.modules['cheeseshop.development'] = self.settings + sys.modules['cheeseshop'].development = self.settings + + def tearDown(self): + # We will clear out sys.modules again to clean up + for m in ['cheeseshop', 'cheeseshop.development']: + del sys.modules[m] + + +class TestTestScript(ScriptTestCase): + + @mock.patch('django.core.management', 'execute_manager') + def test_script(self, execute_manager): + # The test script should execute the standard Django test + # command with any apps given as its arguments. + test.main('cheeseshop.development', 'spamm', 'eggs') + # We only care about the arguments given to execute_manager + self.assertEqual(execute_manager.call_args[1], + {'argv': ['test', 'test', 'spamm', 'eggs']}) + + @mock.patch('django.core.management', 'execute_manager') + def test_deeply_nested_settings(self, execute_manager): + # Settings files can be more than two levels deep. We need to + # make sure the test script can properly import those. To + # demonstrate this we need to add another level to our + # sys.modules entries. + settings = mock.sentinel.SettingsModule + nce = mock.sentinel.NCE + nce.development = settings + sys.modules['cheeseshop'].nce = nce + sys.modules['cheeseshop.nce'] = nce + sys.modules['cheeseshop.nce.development'] = settings + + test.main('cheeseshop.nce.development', 'tilsit', 'stilton') + self.assertEqual(execute_manager.call_args[0], (settings,)) + + @mock.patch('sys', 'exit') + def test_settings_error(self, sys_exit): + # When the settings file cannot be imported the test runner + # wil exit with a message and a specific exit code. + test.main('cheeseshop.tilsit', 'stilton') + self.assertEqual(sys_exit.call_args, ((1,), {})) + +class TestManageScript(ScriptTestCase): + + @mock.patch('django.core.management', 'execute_manager') + def test_script(self, execute_manager): + # The manage script is a replacement for the default manage.py + # script. It has all the same bells and whistles since all it + # does is call the normal Django stuff. + manage.main('cheeseshop.development') + self.assertEqual(execute_manager.call_args, + ((self.settings,), {})) + + @mock.patch('sys', 'exit') + def test_settings_error(self, sys_exit): + # When the settings file cannot be imported the management + # script it wil exit with a message and a specific exit code. + manage.main('cheeseshop.tilsit') + self.assertEqual(sys_exit.call_args, ((1,), {})) + +def setUp(test): + zc.buildout.testing.buildoutSetUp(test) + + # Make a semi permanent download cache to speed up the test + tmp = tempfile.gettempdir() + cache_dir = os.path.join(tmp, 'djangorecipe-test-cache') + if not os.path.exists(cache_dir): + os.mkdir(cache_dir) + + # Create the default.cfg which sets the download cache + home = test.globs['tmpdir']('home') + test.globs['mkdir'](home, '.buildout') + test.globs['write'](home, '.buildout', 'default.cfg', + """ +[buildout] +download-cache = %(cache_dir)s + """ % dict(cache_dir=cache_dir)) + os.environ['HOME'] = home + + zc.buildout.testing.install('zc.recipe.egg', test) + zc.buildout.testing.install_develop('djangorecipe', test) + + +def test_suite(): + return unittest.TestSuite(( + unittest.makeSuite(TestRecipe), + unittest.makeSuite(TestTestScript), + unittest.makeSuite(TestManageScript), + )) diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/tests.pyo b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/tests.pyo Binary files differnew file mode 100644 index 0000000..880b222 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/tests.pyo diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/wsgi.py b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/wsgi.py new file mode 100644 index 0000000..9e9d054 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/wsgi.py @@ -0,0 +1,45 @@ +import sys + +from django.core import management + +def main(settings_file, logfile=None): + try: + mod = __import__(settings_file) + components = settings_file.split('.') + for comp in components[1:]: + mod = getattr(mod, comp) + + except ImportError, e: + sys.stderr.write("Error loading the settings module '%s': %s" + % (settings_file, e)) + sys.exit(1) + + # Setup settings + management.setup_environ(mod) + + if logfile: + import datetime + class logger(object): + def __init__(self, logfile): + self.logfile = logfile + + def write(self, data): + self.log(data) + + def writeline(self, data): + self.log(data) + + def log(self, msg): + line = '%s - %s\n' % ( + datetime.datetime.now().strftime('%Y%m%d %H:%M:%S'), msg) + fp = open(self.logfile, 'a') + try: + fp.write(line) + finally: + fp.close() + sys.stdout = sys.stderr = logger(logfile) + + from django.core.handlers.wsgi import WSGIHandler + + # Run WSGI handler for the application + return WSGIHandler() diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/wsgi.pyo b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/wsgi.pyo Binary files differnew file mode 100644 index 0000000..79288fe --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/wsgi.pyo |