IDE compatible launcher script
by
plone.org Administrator
—
last modified
Sep 08, 2010 01:03 PM
IDE compatible Zope launcher script for Zope buildouts
idelauncher.py
—
Python Source,
5 kB (5930 bytes)
File contents
# -*- coding: utf-8 -*-
"""
Through-the-IDE launch script for Eclipse and Plone 3.1.x.
Assume default builtout folder layout with Omelette. Drop this script to instance/bin folder. Use instance folder as the
working folder when running the script.
Related tutorial: http://plone.org/documentation/how-to/developing-plone-with-eclipse-ide
Omelette: http://theploneblog.org/blog/archive/2008/03/10/collective-recipe-omelette-for-more-navigable-eggs
Please visit us at http://mfabrik.com
Use following arguments:
To start Plone server.
idelauncher.py (no parameters)
To run all tests in a product:
test -s plone.app.contentrules
To run a specific test case:
test -s plone.app.contentrules -t TestWorkflowTriggering (py modulename without extension)
Zope does not give an error if the product/case is missing, but runs 0 tests.
Version history
===============
1.8: Plone 4 compatibility
1.7: Added optional use of "debug-instance" launcher if present
1.6: Fixed typo in UNIX instance script name
1.5: Updated to Windows compatibility
1.4: Added Zope debug shell compatiblity
1.3: Added pydevd compatibility
1.2: Fixed signal handler problems with collective.autorestart (pyinotify)
1.1: Fixed unit test running problems
"""
__author__ = "Mikko Ohtamaa <mikko.ohtamaa@twinapex.com>"
__docformat__ = "epytext"
__license__ = "3-clause BSD"
__copyright__ = "2008-2010 Twinapex Research"
__version__ = "1.5"
__url__ = "http://plone.org/documentation/kb/developing-plone-with-eclipse/ide-compatible-launcher-script"
import os
import sys
# Guess our working directory based on the location of this file
module = sys.modules[__name__]
PROJECT_FOLDER=os.path.join(os.path.dirname(module.__file__), "..")
# Set up Zope environment variables
os.environ["ZOPE_HOME"]=os.path.join(PROJECT_FOLDER, "parts/zope2")
os.environ["INSTANCE_HOME"]=os.path.join(PROJECT_FOLDER, "parts/instance")
os.environ["CONFIG_FILE"]=os.path.join(PROJECT_FOLDER, "parts/instance/etc/zope.conf")
os.environ["SOFTWARE_HOME"]=os.path.join(PROJECT_FOLDER, "parts/zope2/lib/python")
# Omelette and other path completion goodies must not exist in sys.path when launching the instance.
# PyDev inserts it there for import autocompletion, but Plone
# chokes if it finds duplicate imports and other Omelette
# quirkies during start up
# python2.4 -> standard python library
# pysrc -> pydevd remote debugger support
allowed_path_marks = ["python2.4", # System Pythons
"python2.5",
"python2.6",
"python2.7",
"pysrc", # PyDev IDE
"python\\lib", # Windows system Python
"DLL" #
]
def is_good_path(path):
for p in allowed_path_marks:
if p in path:
return True
return False
# Make sure that Python path contains only eggs provided by the system
sys.path = [ x for x in sys.path if is_good_path(x) ]
# Use instance script to initialize PYTHONPATH
if sys.platform == "win32":
script = "instance-script.py"
else:
# Also for unix try debug-instance
for name in ["debug-instance", "instance", "xxx"]:
path = os.path.join(PROJECT_FOLDER, "bin", name)
if os.path.exists(path):
script = name
break
if name == "xxx":
print "Could not guess Zope start-up script name in bin folder"
sys.exit(1)
# These must be updated accordingly
os.environ["INSTANCE_HOME"]=os.path.join(PROJECT_FOLDER, "parts/" + script)
os.environ["CONFIG_FILE"]=os.path.join(PROJECT_FOLDER, "parts/" + script + "/etc/zope.conf")
print "Starting Zope with script " + script + " and configuration:" + str(os.environ.get("CONFIG_FILE"))
instance_script = open(os.path.join(PROJECT_FOLDER, "bin", script), "rt")
data = ""
for line in instance_script:
if line.startswith("if __name__ =="):
# A hack to evaluate sys.path imports from instance script
break
data += line + "\n"
instance_script.close()
exec(data, globals())
def fix_signal_handlers():
""" Signal handlers + pyinotify are incompatible combination, preventing running collective.autorestart from IDE """
from Signals import Signals
def dummy_register(loggers):
""" Monkey-patched signal registerer - do not register any signals """
pass
Signals.registerZopeSignals = dummy_register
if len(sys.argv) > 1 and sys.argv[1] in ("test", "debug"):
# Start Zope test runner or console mode.
# We can invoke this using zope2instance.ctl, since its do_test()
# does not fork a new process
old_arg = sys.argv[:]
sys.argv = [ "ctl.py", "-C", os.environ["CONFIG_FILE"], sys.argv[1]]
sys.argv += old_arg[2:]
from plone.recipe.zope2instance import ctl
ctl.main(sys.argv[1:])
else:
# Start zope instance as a web server
# Zope launcher module
ZOPE_RUN = os.path.join(os.environ["SOFTWARE_HOME"], "Zope2/Startup/run.py")
if not os.path.exists(ZOPE_RUN):
# Plone 4
import Zope2.Startup.run
ZOPE_RUN = Zope2.Startup.run.__file__
if ZOPE_RUN.endswith(".pyc"):
# Run as .py file
ZOPE_RUN = ZOPE_RUN[:-1]
# Tinker with command-line to emulate normal Zope launch
sys.argv = [ ZOPE_RUN, "-C", os.environ["CONFIG_FILE"], "-X", "debug-mode=on"]
fix_signal_handlers()
# Instead of spawning zopectl and Zope in another process, execute Plone in the context of this Python interpreter
# to have pdb control over the code
execfile(ZOPE_RUN)
