backport stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Fri, 15 Oct 2010 11:48:16 +0200
changeset 6507 df2527c645cd
parent 6500 e288df2e2f18 (current diff)
parent 6506 c1661ea815dc (diff)
child 6509 b717a6cb337b
backport stable
cwconfig.py
setup.py
--- a/__init__.py	Fri Oct 15 11:33:06 2010 +0200
+++ b/__init__.py	Fri Oct 15 11:48:16 2010 +0200
@@ -146,3 +146,4 @@
         CW_EVENT_MANAGER.bind(event, func, *args, **kwargs)
         return func
     return _decorator
+import cubicweb.__setuptools_hack__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/__setuptools_hack__.py	Fri Oct 15 11:48:16 2010 +0200
@@ -0,0 +1,30 @@
+from os import path as osp
+import sys
+import os
+
+def in_egg(path):
+    head, tail = osp.split(path)
+    while tail:
+        if tail.endswith('.egg'):
+            return True
+        head, tail = osp.split(head)
+    return False
+
+if in_egg(__file__):
+    from cubicweb.cwconfig import _find_prefix
+    INSTALL_PREFIX = _find_prefix()
+    if not osp.exists(osp.join(INSTALL_PREFIX, 'share', 'cubicweb', 'migration')):
+        print >> sys.stderr, 'copying cubicweb content to the expected location'
+        from shutil import copytree
+        import tarfile
+        import tempfile
+        from pkg_resources import Requirement, resource_filename
+        from functools import partial
+        file_path = partial(resource_filename, Requirement.parse("cubicweb"))
+        for df in ('share', 'lib'):
+            # Tar are used to merge with destination directory
+            tmp_file = tempfile.NamedTemporaryFile(suffix='.tar')
+            tmp_tar  = tarfile.TarFile(tmp_file.name, mode='w')
+            tmp_tar.add(file_path(df), arcname=df)
+            tmp_tar  = tarfile.TarFile(tmp_file.name, mode='r')
+            tmp_tar.extractall(path=INSTALL_PREFIX)
--- a/cwconfig.py	Fri Oct 15 11:33:06 2010 +0200
+++ b/cwconfig.py	Fri Oct 15 11:48:16 2010 +0200
@@ -152,7 +152,7 @@
 
 from cubicweb import (CW_SOFTWARE_ROOT, CW_MIGRATION_MAP,
                       ConfigurationError, Binary)
-from cubicweb.toolsutils import env_path, create_dir
+from cubicweb.toolsutils import create_dir
 
 CONFIGURATIONS = []
 
@@ -202,7 +202,8 @@
     old_prefix = None
     if not isdir(start_path):
         prefix = dirname(start_path)
-    while not isdir(join(prefix, 'share', 'cubicweb')) and prefix != old_prefix:
+    while (not isdir(join(prefix, 'share', 'cubicweb'))
+          or prefix.endswith('.egg')) and prefix != old_prefix:
         old_prefix = prefix
         prefix = dirname(prefix)
     if isdir(join(prefix, 'share', 'cubicweb')):
@@ -284,6 +285,7 @@
     _INSTALL_PREFIX = os.environ['CW_INSTALL_PREFIX']
 except KeyError:
     _INSTALL_PREFIX = _find_prefix()
+_USR_INSTALL = _INSTALL_PREFIX == '/usr'
 
 class CubicWebNoAppConfiguration(ConfigurationMixIn):
     """base class for cubicweb configuration without a specific instance directory
@@ -305,7 +307,7 @@
         mode = _forced_mode or 'system'
         _CUBES_DIR = join(_INSTALL_PREFIX, 'share', 'cubicweb', 'cubes')
 
-    CUBES_DIR = env_path('CW_CUBES_DIR', _CUBES_DIR, 'cubes', checkexists=False)
+    CUBES_DIR = abspath(os.environ.get('CW_CUBES_DIR', _CUBES_DIR))
     CUBES_PATH = os.environ.get('CW_CUBES_PATH', '').split(os.pathsep)
 
     options = (
@@ -805,11 +807,11 @@
 
     if CubicWebNoAppConfiguration.mode == 'user':
         _INSTANCES_DIR = expanduser('~/etc/cubicweb.d/')
-    else: #mode = 'system'
-        if _INSTALL_PREFIX == '/usr':
-            _INSTANCES_DIR = '/etc/cubicweb.d/'
-        else:
-            _INSTANCES_DIR = join(_INSTALL_PREFIX, 'etc', 'cubicweb.d')
+    #mode == system'
+    elif _USR_INSTALL:
+        _INSTANCES_DIR = '/etc/cubicweb.d/'
+    else:
+        _INSTANCES_DIR = join(_INSTALL_PREFIX, 'etc', 'cubicweb.d')
 
     if os.environ.get('APYCOT_ROOT'):
         _cubes_init = join(CubicWebNoAppConfiguration.CUBES_DIR, '__init__.py')
@@ -862,7 +864,7 @@
     @classmethod
     def instances_dir(cls):
         """return the control directory"""
-        return env_path('CW_INSTANCES_DIR', cls._INSTANCES_DIR, 'registry')
+        return abspath(os.environ.get('CW_INSTANCES_DIR', cls._INSTANCES_DIR))
 
     @classmethod
     def migration_scripts_dir(cls):
@@ -934,20 +936,27 @@
                     path = '%s-%s.log' % (basepath, i)
                     i += 1
             return path
-        return '/var/log/cubicweb/%s-%s.log' % (self.appid, self.name)
+        if _USR_INSTALL:
+            return '/var/log/cubicweb/%s-%s.log' % (self.appid, self.name)
+        else:
+            log_path = os.path.join(_INSTALL_PREFIX, 'var', 'log', 'cubicweb', '%s-%s.log')
+            return log_path % (self.appid, self.name)
+
+
 
     def default_pid_file(self):
         """return default path to the pid file of the instance'server"""
         if self.mode == 'system':
-            # XXX not under _INSTALL_PREFIX, right?
-            default = '/var/run/cubicweb/'
+            if _USR_INSTALL:
+                default = '/var/run/cubicweb/'
+            else:
+                default = os.path.join(_INSTALL_PREFIX, 'var', 'run', 'cubicweb')
         else:
             import tempfile
             default = tempfile.gettempdir()
         # runtime directory created on startup if necessary, don't check it
         # exists
-        rtdir = env_path('CW_RUNTIME_DIR', default, 'run time',
-                         checkexists=False)
+        rtdir = abspath(os.environ.get('CW_RUNTIME_DIR', default))
         return join(rtdir, '%s-%s.pid' % (self.appid, self.name))
 
     # instance methods used to get instance specific resources #############
@@ -971,11 +980,13 @@
     @property
     def appdatahome(self):
         if self.mode == 'system':
-            # XXX not under _INSTALL_PREFIX, right?
-            iddir = '/var/lib/cubicweb/instances/'
+            if _USR_INSTALL:
+                iddir = os.path.join('/var','lib', 'cubicweb', 'instances')
+            else:
+                iddir = os.path.join(_INSTALL_PREFIX, 'var', 'lib', 'cubicweb', 'instances')
         else:
             iddir = self.instances_dir()
-        iddir = env_path('CW_INSTANCES_DATA_DIR', iddir, 'additional data')
+        iddir = abspath(os.environ.get('CW_INSTANCES_DATA_DIR', iddir))
         return join(iddir, self.appid)
 
     def init_cubes(self, cubes):
--- a/cwctl.py	Fri Oct 15 11:33:06 2010 +0200
+++ b/cwctl.py	Fri Oct 15 11:48:16 2010 +0200
@@ -63,7 +63,10 @@
         raise ExecutionError('can\'t kill process %s' % pid)
 
 def list_instances(regdir):
-    return sorted(idir for idir in listdir(regdir) if isdir(join(regdir, idir)))
+    if isdir(regdir):
+        return sorted(idir for idir in listdir(regdir) if isdir(join(regdir, idir)))
+    else:
+        return []
 
 def detect_available_modes(templdir):
     modes = []
--- a/debian/cubicweb-common.install.in	Fri Oct 15 11:33:06 2010 +0200
+++ b/debian/cubicweb-common.install.in	Fri Oct 15 11:48:16 2010 +0200
@@ -1,5 +1,5 @@
 debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/common/ usr/lib/PY_VERSION/site-packages/cubicweb
 debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/entities/ usr/lib/PY_VERSION/site-packages/cubicweb
 debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/ext/ usr/lib/PY_VERSION/site-packages/cubicweb
-debian/tmp/usr/share/cubicweb/cubes/shared/i18n usr/share/cubicweb/cubes/shared/
+debian/tmp/usr/share/cubicweb/cubes/ usr/share/cubicweb/
 debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/*.py usr/share/pyshared/cubicweb
--- a/debian/rules	Fri Oct 15 11:33:06 2010 +0200
+++ b/debian/rules	Fri Oct 15 11:48:16 2010 +0200
@@ -53,8 +53,6 @@
 	rm -rf debian/cubicweb-common/usr/lib/${PY_VERSION}/site-packages/cubicweb/ext/test
 	rm -rf debian/cubicweb-common/usr/lib/${PY_VERSION}/site-packages/cubicweb/entities/test
 
-	# cubes directory must be managed as a valid python module
-	touch debian/cubicweb-common/usr/share/cubicweb/cubes/__init__.py
 
 %: %.in
 	sed "s/PY_VERSION/${PY_VERSION}/g" < $< > $@
--- a/setup.py	Fri Oct 15 11:33:06 2010 +0200
+++ b/setup.py	Fri Oct 15 11:48:16 2010 +0200
@@ -31,10 +31,12 @@
         raise ImportError() # do as there is no setuptools
     from setuptools import setup
     from setuptools.command import install_lib
+    from setuptools.command import install_data
     USE_SETUPTOOLS = True
 except ImportError:
     from distutils.core import setup
     from distutils.command import install_lib
+    from distutils.command import install_data
     USE_SETUPTOOLS = False
 
 # import required features
@@ -163,6 +165,16 @@
                 dest = join(self.install_dir, base, directory)
                 export(directory, dest, verbose=False)
 
+class MyInstallData(install_data.install_data):
+    def run(self):
+        """overridden from install_data class"""
+        install_data.install_data.run(self)
+        path = join(self.install_dir, 'share', 'cubicweb', 'cubes', '__init__.py')
+        ini = open(path, 'w')
+        ini.write('# Cubicweb cubes directory\n')
+        ini.close()
+
+
 def install(**kwargs):
     """setup entry point"""
     if USE_SETUPTOOLS:
@@ -188,7 +200,7 @@
                  author=author, author_email=author_email,
                  scripts=ensure_scripts(scripts), data_files=data_files,
                  ext_modules=ext_modules,
-                 cmdclass={'install_lib': MyInstallLib},
+                 cmdclass={'install_lib': MyInstallLib, 'install_data': MyInstallData},
                  **kwargs
                  )
 
--- a/toolsutils.py	Fri Oct 15 11:33:06 2010 +0200
+++ b/toolsutils.py	Fri Oct 15 11:48:16 2010 +0200
@@ -194,30 +194,6 @@
                 config_file, ex)
     return config
 
-def env_path(env_var, default, name, checkexists=True):
-    """get a path specified in a variable or using the default value and return
-    it.
-
-    :type env_var: str
-    :param env_var: name of an environment variable
-
-    :type default: str
-    :param default: default value if the environment variable is not defined
-
-    :type name: str
-    :param name: the informal name of the path, used for error message
-
-    :rtype: str
-    :return: the value of the environment variable or the default value
-
-    :raise `ConfigurationError`: if the returned path does not exist
-    """
-    path = environ.get(env_var, default)
-    if checkexists and not exists(path):
-        raise ConfigurationError('%s directory %s doesn\'t exist' % (name, path))
-    return abspath(path)
-
-
 
 _HDLRS = {}
 
--- a/web/views/iprogress.py	Fri Oct 15 11:33:06 2010 +0200
+++ b/web/views/iprogress.py	Fri Oct 15 11:48:16 2010 +0200
@@ -178,8 +178,11 @@
     @classmethod
     def overrun(cls, iprogress):
         """overrun = done + todo - """
-        if iprogress.done + iprogress.todo > iprogress.revised_cost:
-            overrun = iprogress.done + iprogress.todo - iprogress.revised_cost
+        done = iprogress.done or 0
+        todo = iprogress.todo or 0
+        revised_cost = iprogress.revised_cost or 0
+        if done + todo > revised_cost:
+            overrun = done + todo - revised_cost
         else:
             overrun = 0
         if overrun < cls.precision:
@@ -189,19 +192,19 @@
     @classmethod
     def overrun_percentage(cls, iprogress):
         """pourcentage overrun = overrun / budget"""
-        if iprogress.revised_cost == 0:
+        revised_cost = iprogress.revised_cost or 0
+        if revised_cost == 0:
             return 0
-        else:
-            return cls.overrun(iprogress) * 100. / iprogress.revised_cost
+        return cls.overrun(iprogress) * 100. / revised_cost
 
     def cell_call(self, row, col):
         self._cw.add_css('cubicweb.iprogress.css')
         self._cw.add_js('cubicweb.iprogress.js')
         entity = self.cw_rset.get_entity(row, col)
         iprogress = entity.cw_adapt_to('IProgress')
-        done = iprogress.done
-        todo = iprogress.todo
-        budget = iprogress.revised_cost
+        done = iprogress.done or 0
+        todo = iprogress.todo or 0
+        budget = iprogress.revised_cost or 0
         if budget == 0:
             pourcent = 100
         else: