script.py 3.34 KB
Newer Older
1
2
3
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# Andre Anjos <andre.dos.anjos@gmail.com>
4
# Mon  4 Feb 14:12:24 2013
5
6
7
8
9

"""Builds custom scripts with the right paths for external dependencies
installed on different prefixes.
"""

10
import sys
11
import logging
12
13
from zc.recipe.egg import Scripts

14
from . import tools
15
from .envwrapper import EnvironmentWrapper
16
17

import zc.buildout.easy_install
18
19
def _script(module_name, attrs, path, dest, arguments, initialization, rsetup):
  """Default script generator"""
20

21
22
23
24
25
26
  if zc.buildout.easy_install.is_win32: dest += '-script.py'

  python = zc.buildout.easy_install._safe_arg(sys.executable)

  # the "difference": re-order python paths with a preference for locals
  realpath = [k.strip().strip("'").strip('"') for k in path.split(",\n")]
27
  realpath = [k.strip() for k in realpath if k.strip()]
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
  path = ",\n  ".join(["'%s'" % k for k in realpath if k not in sys.path])

  contents = zc.buildout.easy_install.script_template % dict(
      python = python,
      path = path,
      module_name = module_name,
      attrs = attrs,
      arguments = arguments,
      initialization = initialization,
      relative_paths_setup = rsetup,
      )

  return zc.buildout.easy_install._create_script(contents, dest)

# Monkey patches the default script generator
zc.buildout.easy_install._script = _script
André Anjos's avatar
André Anjos committed
44

45
46
47
48
49
50
51
52
53
54
55
56
class Recipe(Scripts):
  """Just creates a given script with the "correct" paths
  """

  def __init__(self, buildout, name, options):

    self.buildout = buildout
    self.name = name
    self.options = options

    self.logger = logging.getLogger(self.name)

André Anjos's avatar
André Anjos committed
57
    # Gets a personalized eggs list or the one from buildout
58
    self.eggs = tools.eggs(buildout['buildout'], options, name)
59

André Anjos's avatar
André Anjos committed
60
    # Gets a personalized prefixes list or the one from buildout
61
62
    self.prefixes = tools.get_prefixes(buildout['buildout'])
    self.user_paths = tools.find_site_packages(self.prefixes)
André Anjos's avatar
André Anjos committed
63

64
65
    # Builds an environment wrapper, in case dependent packages need to be
    # compiled
66
67
    self.envwrapper = EnvironmentWrapper(self.logger,
        tools.debug(buildout['buildout']), self.prefixes)
68
69

    # initializes the script infrastructure
70
    super(Recipe, self).__init__(buildout, name, options)
71
72
73
74
75
76
77
78
79

  def working_set(self, extra=()):
    """Separate method to just get the working set - overriding zc.recipe.egg

    This is intended for reuse by similar recipes.
    """

    distributions = self.eggs + list(extra)

80
81
82
83
84
85
86
87
88
89
    if tools.offline(self.buildout['buildout']):

      ws = tools.working_set(self.buildout['buildout'], self.prefixes)
      ws = tools.filter_working_set_hard(ws, distributions)

    else:

      ws = tools.working_set(self.buildout['buildout'], self.prefixes)

      if tools.newest(self.buildout['buildout']):
90
91
92
93
94

        for d in distributions:
          tools.install_package(self.buildout['buildout'], d, ws)
        ws = tools.filter_working_set_hard(ws, distributions)

95
96
      else: #only installs packages which are not yet installed

97
98
99
        ws, to_install = tools.filter_working_set_soft(ws, distributions)
        for d in to_install:
          tools.install_package(self.buildout['buildout'], d, ws)
André Anjos's avatar
André Anjos committed
100

101
102
    return self.eggs, ws

André Anjos's avatar
André Anjos committed
103
104
105
  def install_on_wrapped_env(self):
    return tuple(super(Recipe, self).install())

106
  def install(self):
107
    self.envwrapper.set()
André Anjos's avatar
André Anjos committed
108
    retval = self.install_on_wrapped_env()
109
110
    self.envwrapper.unset()
    return retval
111
112

  update = install