Commits

Gael Pasgrimaud  committed bb64c1a

avoid duplicated intallation by buildout

  • Participants
  • Parent commits 98686ae

Comments (0)

Files changed (1)

File gp/recipe/pip/__init__.py

 # -*- coding: utf-8 -*-
 """Recipe pip"""
+import pkg_resources
+import zc.buildout
 import zc.buildout.easy_install
 from zc.recipe.egg import Scripts
 from subprocess import call
             break
     return executable
 
-class Recipe(object):
+class Recipe(Scripts):
     """zc.buildout recipe"""
 
-    def __init__(self, buildout, name, options):
-        self.buildout, self.name, self.options = buildout, name, options
-
     def pip_install(self, part_dir, build_dir, src_dir, extra_args):
         print 'pip install %s' % ' '.join(extra_args)
 
         if code != 0:
             raise RuntimeError('An error occur during pip installation. See %s-log.txt' % self.name)
 
-    def install(self):
+    def working_set(self, extra=()):
+        options = self.options
+
         part_dir = join(self.buildout['buildout']['parts-directory'], 'pip')
         if 'virtualenv' in self.buildout['buildout']:
             part_dir = self.buildout['buildout']['virtualenv']
-        if 'virtualenv' in self.options:
-            part_dir = self.options['virtualenv']
+        if 'virtualenv' in options:
+            part_dir = options['virtualenv']
 
         build_dir = join(part_dir, 'build')
         if 'build-directory' in self.buildout['buildout']:
             build_dir = self.buildout['buildout']['build-directory']
-        if 'build-directory' in self.options:
-            build_dir = self.options['build-directory']
+        if 'build-directory' in options:
+            build_dir = options['build-directory']
 
-        src_dir = self.options.get('sources-directory',
-                                   join(self.buildout['buildout']['directory'], 'src'))
+        src_dir = options.get('sources-directory',
+                              join(self.buildout['buildout']['directory'], 'src'))
 
         # get buildout versions
         versions_option = self.buildout['buildout'].get('versions')
         self.pip_install(part_dir, build_dir, src_dir, [])
 
         # VSC
-        editables = to_list(self.options.get('editables', ''))
+        editables = to_list(options.get('editables', ''))
         for e in editables:
             self.pip_install(part_dir, build_dir, src_dir, ['-e', e])
 
         # packages / bundles. add version if needed
-        installs = to_list(self.options.get('install', ''))
+        installs = to_list(options.get('install', ''))
         for i in installs:
             for k in buildout_versions:
                 if i.endswith(k):
 
         # retrieve venv's site-packages and executable
         executable = get_executable(part_dir)
+        assert os.path.isfile(executable)
+        options['executable'] = executable
+
         site_packages = glob.glob(join(part_dir, 'lib', '*', 'site-packages'))[0]
-        if site_packages not in sys.path:
-            sys.path.insert(0, site_packages)
-
-        # retrieve versions from egg-info
-        egg_infos = glob.glob(join(site_packages, '*.egg-info'))
-        eggs = []
-        versions = []
-        for info in egg_infos:
-            info = os.path.basename(info)
-            name, ver, r = info.split('-', 2)
-            # only add eggs available in install
-            for i in installs:
-                if name in i:
-                    eggs.append(name)
-                    versions.append((name, ver))
-        versions = dict(versions)
-
-        # update with buildout versions
-        versions.update(buildout_versions)
-
-        zc.buildout.easy_install.default_versions(versions)
-
-        # set eggs directory and executable
-        _options = self.buildout['buildout'].copy()
-        self.buildout['buildout']['newest'] = 'false'
-        self.buildout['buildout']['executable'] = executable
-
-        # clean copy of options
-        options = {}
-        for k in self.options:
-            options[k] = self.options[k]
+        assert os.path.isdir(site_packages)
 
         # move .egg-link from site-packages and append develop eggs to eggs list
         dev_eggs_dir = self.buildout['buildout']['develop-eggs-directory']
         for filename in glob.glob(join(site_packages, '*.egg-link')):
             name =  os.path.basename(filename)
-            eggs.append(name.replace('.egg-link', ''))
             os.rename(filename, join(dev_eggs_dir, name))
 
-        # add eggs found in venv to eggs option
-        options['eggs'] = '\n'.join(eggs) + '\n' + self.options.get('eggs', '')
+        # This came from zc.recipe.egg but we need to add venv's WorkingSet
+        ws = workink_set=pkg_resources.WorkingSet([site_packages])
 
-        # add VCS path as extra_paths
-        extra_paths = glob.glob(join(src_dir, '*'))
+        kw = {}
+        always_unzip = options.get('unzip')
+        if always_unzip is not None:
+            if always_unzip not in ('true', 'false'):
+                raise zc.buildout.UserError("Invalid value for unzip, %s"
+                                            % always_unzip)
+            kw['always_unzip'] = always_unzip == 'true'
 
-        # get eggs already in sys path and add them to extra_paths
-        eggs_dir = self.buildout['buildout']['eggs-directory']
-        options['extra-paths'] = '\n'.join([p for p in sys.path if p.startswith(eggs_dir)])
+        distributions = to_list(options.get('eggs', ''))
+        ws = zc.buildout.easy_install.install(
+            distributions,
+            options['eggs-directory'],
+            links = self.links,
+            index = self.index,
+            executable = executable,
+            path=[options['develop-eggs-directory']],
+            newest=self.buildout['buildout'].get('newest') == 'true',
+            allow_hosts=self.allow_hosts,
+            working_set=ws,
+            **kw)
 
-        # run the recipe
-        egg = Scripts(self.buildout, self.name, options)
-        egg.install()
+        distributions.extend([d.project_name for d in ws])
 
-        # restore options
-        for k in _options:
-            self.buildout['buildout'][k] = _options[k]
-        versions = self.buildout['buildout'].get('versions')
-        if versions:
-            zc.buildout.easy_install.default_versions(dict(self.buildout[versions]))
+        return distributions, ws
 
-        return tuple()
 
-    update = install
-
+    def install(self):
+        if self.buildout['buildout']['offline'] == 'true':
+            return ()
+        return Scripts.install(self)