|
1 Debugging buildouts |
|
2 =================== |
|
3 |
|
4 Buildouts can be pretty complex. When things go wrong, it isn't |
|
5 always obvious why. Errors can occur due to problems in user input or |
|
6 due to bugs in zc.buildout or recipes. When an error occurs, Python's |
|
7 post-mortem debugger can be used to inspect the state of the buildout |
|
8 or recipe code where the error occurred. To enable this, use the -D |
|
9 option to the buildout. Let's create a recipe that has a bug: |
|
10 |
|
11 >>> mkdir(sample_buildout, 'recipes') |
|
12 |
|
13 >>> write(sample_buildout, 'recipes', 'mkdir.py', |
|
14 ... """ |
|
15 ... import os, zc.buildout |
|
16 ... |
|
17 ... class Mkdir: |
|
18 ... |
|
19 ... def __init__(self, buildout, name, options): |
|
20 ... self.name, self.options = name, options |
|
21 ... options['path'] = os.path.join( |
|
22 ... buildout['buildout']['directory'], |
|
23 ... options['path'], |
|
24 ... ) |
|
25 ... |
|
26 ... def install(self): |
|
27 ... directory = self.options['directory'] |
|
28 ... os.mkdir(directory) |
|
29 ... return directory |
|
30 ... |
|
31 ... def update(self): |
|
32 ... pass |
|
33 ... """) |
|
34 |
|
35 >>> write(sample_buildout, 'recipes', 'setup.py', |
|
36 ... """ |
|
37 ... from setuptools import setup |
|
38 ... |
|
39 ... setup(name = "recipes", |
|
40 ... entry_points = {'zc.buildout': ['mkdir = mkdir:Mkdir']}, |
|
41 ... ) |
|
42 ... """) |
|
43 |
|
44 And create a buildout that uses it: |
|
45 |
|
46 >>> write(sample_buildout, 'buildout.cfg', |
|
47 ... """ |
|
48 ... [buildout] |
|
49 ... develop = recipes |
|
50 ... parts = data-dir |
|
51 ... |
|
52 ... [data-dir] |
|
53 ... recipe = recipes:mkdir |
|
54 ... path = mystuff |
|
55 ... """) |
|
56 |
|
57 If we run the buildout, we'll get an error: |
|
58 |
|
59 >>> print system(buildout), |
|
60 Develop: '/sample-buildout/recipes' |
|
61 Installing data-dir. |
|
62 While: |
|
63 Installing data-dir. |
|
64 Error: Missing option: data-dir:directory |
|
65 |
|
66 |
|
67 If we want to debug the error, we can add the -D option. Here's we'll |
|
68 supply some input: |
|
69 |
|
70 >>> print system(buildout+" -D", """\ |
|
71 ... up |
|
72 ... p self.options.keys() |
|
73 ... q |
|
74 ... """), |
|
75 Develop: '/sample-buildout/recipes' |
|
76 Installing data-dir. |
|
77 > /zc/buildout/buildout.py(925)__getitem__() |
|
78 -> raise MissingOption("Missing option: %s:%s" % (self.name, key)) |
|
79 (Pdb) > /sample-buildout/recipes/mkdir.py(14)install() |
|
80 -> directory = self.options['directory'] |
|
81 (Pdb) ['path', 'recipe'] |
|
82 (Pdb) While: |
|
83 Installing data-dir. |
|
84 Traceback (most recent call last): |
|
85 File "/zc/buildout/buildout.py", line 1352, in main |
|
86 getattr(buildout, command)(args) |
|
87 File "/zc/buildout/buildout.py", line 383, in install |
|
88 installed_files = self[part]._call(recipe.install) |
|
89 File "/zc/buildout/buildout.py", line 961, in _call |
|
90 return f() |
|
91 File "/sample-buildout/recipes/mkdir.py", line 14, in install |
|
92 directory = self.options['directory'] |
|
93 File "/zc/buildout/buildout.py", line 925, in __getitem__ |
|
94 raise MissingOption("Missing option: %s:%s" % (self.name, key)) |
|
95 MissingOption: Missing option: data-dir:directory |
|
96 <BLANKLINE> |
|
97 Starting pdb: |