source: TI12-security/trunk/NDGSecurity/python/buildout/ndgsecurity/eggs/zc.buildout-1.2.1-py2.5.egg/zc/buildout/easy_install.txt @ 7081

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg-security/TI12-security/trunk/NDGSecurity/python/buildout/ndgsecurity/eggs/zc.buildout-1.2.1-py2.5.egg/zc/buildout/easy_install.txt@7081
Revision 7081, 40.8 KB checked in by pjkersha, 11 years ago (diff)
  • Property svn:keywords set to Id
Line 
1Python API for egg and script installation
2==========================================
3
4The easy_install module provides some functions to provide support for
5egg and script installation.  It provides functionality at the python
6level that is similar to easy_install, with a few exceptions:
7
8- By default, we look for new packages *and* the packages that
9  they depend on.  This is somewhat like (and uses) the --upgrade
10  option of easy_install, except that we also upgrade required
11  packages.
12
13- If the highest-revision package satisfying a specification is
14  already present, then we don't try to get another one.  This saves a
15  lot of search time in the common case that packages are pegged to
16  specific versions.
17
18- If there is a develop egg that satisfies a requirement, we don't
19  look for additional distributions.  We always give preference to
20  develop eggs.
21
22- Distutils options for building extensions can be passed.
23
24Distribution installation
25-------------------------
26
27The easy_install module provides a function, install, for installing one
28or more packages and their dependencies.  The install function takes 2
29positional arguments:
30
31- An iterable of setuptools requirement strings for the distributions
32  to be installed, and
33
34- A destination directory to install to and to satisfy requirements
35  from.  The destination directory can be None, in which case, no new
36  distributions are downloaded and there will be an error if the
37  needed distributions can't be found among those already installed.
38
39It supports a number of optional keyword arguments:
40
41links
42   A sequence of URLs, file names, or directories to look for
43   links to distributions.
44
45index
46   The URL of an index server, or almost any other valid URL. :)
47
48   If not specified, the Python Package Index,
49   http://pypi.python.org/simple/, is used.  You can specify an
50   alternate index with this option.  If you use the links option and
51   if the links point to the needed distributions, then the index can
52   be anything and will be largely ignored.  In the examples, here,
53   we'll just point to an empty directory on our link server.  This
54   will make our examples run a little bit faster.
55
56executable
57   A path to a Python executable.  Distributions will be installed
58   using this executable and will be for the matching Python version.
59
60path
61   A list of additional directories to search for locally-installed
62   distributions.
63
64always_unzip
65   A flag indicating that newly-downloaded distributions should be
66   directories even if they could be installed as zip files.
67
68working_set
69   An existing working set to be augmented with additional
70   distributions, if necessary to satisfy requirements.  This allows
71   you to call install multiple times, if necessary, to gather
72   multiple sets of requirements.
73
74newest
75   A boolean value indicating whether to search for new distributions
76   when already-installed distributions meet the requirement.  When
77   this is true, the default, and when the destination directory is
78   not None, then the install function will search for the newest
79   distributions that satisfy the requirements.
80
81versions
82   A dictionary mapping project names to version numbers to be used
83   when selecting distributions.  This can be used to specify a set of
84   distribution versions independent of other requirements.
85
86use_dependency_links
87   A flag indicating whether to search for dependencies using the
88   setup dependency_links metadata or not. If true, links are searched
89   for using dependency_links in preference to other
90   locations. Defaults to true.
91
92relative_paths
93   Adjust egg paths so they are relative to the script path.  This
94   allows scripts to work when scripts and eggs are moved, as long as
95   they are both moved in the same way.
96
97The install method returns a working set containing the distributions
98needed to meet the given requirements.
99
100We have a link server that has a number of eggs:
101
102    >>> print get(link_server),
103    <html><body>
104    <a href="bigdemo-0.1-py2.4.egg">bigdemo-0.1-py2.4.egg</a><br>
105    <a href="demo-0.1-py2.4.egg">demo-0.1-py2.4.egg</a><br>
106    <a href="demo-0.2-py2.4.egg">demo-0.2-py2.4.egg</a><br>
107    <a href="demo-0.3-py2.4.egg">demo-0.3-py2.4.egg</a><br>
108    <a href="demo-0.4c1-py2.4.egg">demo-0.4c1-py2.4.egg</a><br>
109    <a href="demoneeded-1.0.zip">demoneeded-1.0.zip</a><br>
110    <a href="demoneeded-1.1.zip">demoneeded-1.1.zip</a><br>
111    <a href="demoneeded-1.2c1.zip">demoneeded-1.2c1.zip</a><br>
112    <a href="extdemo-1.4.zip">extdemo-1.4.zip</a><br>
113    <a href="index/">index/</a><br>
114    <a href="other-1.0-py2.4.egg">other-1.0-py2.4.egg</a><br>
115    </body></html>
116
117Let's make a directory and install the demo egg to it, using the demo:
118
119    >>> dest = tmpdir('sample-install')
120    >>> import zc.buildout.easy_install
121    >>> ws = zc.buildout.easy_install.install(
122    ...     ['demo==0.2'], dest,
123    ...     links=[link_server], index=link_server+'index/')
124
125We requested version 0.2 of the demo distribution to be installed into
126the destination server.  We specified that we should search for links
127on the link server and that we should use the (empty) link server
128index directory as a package index.
129
130The working set contains the distributions we retrieved.
131
132    >>> for dist in ws:
133    ...     print dist
134    demo 0.2
135    demoneeded 1.1
136
137We got demoneeded because it was a dependency of demo.
138
139And the actual eggs were added to the eggs directory.
140
141    >>> ls(dest)
142    -  demo-0.2-py2.4.egg
143    -  demoneeded-1.1-py2.4.egg
144
145If we remove the version restriction on demo, but specify a false
146value for newest, no new distributions will be installed:
147
148    >>> ws = zc.buildout.easy_install.install(
149    ...     ['demo'], dest, links=[link_server], index=link_server+'index/',
150    ...     newest=False)
151    >>> ls(dest)
152    -  demo-0.2-py2.4.egg
153    -  demoneeded-1.1-py2.4.egg
154
155If we leave off the newest option, we'll get an update for demo:
156
157    >>> ws = zc.buildout.easy_install.install(
158    ...     ['demo'], dest, links=[link_server], index=link_server+'index/')
159    >>> ls(dest)
160    -  demo-0.2-py2.4.egg
161    -  demo-0.3-py2.4.egg
162    -  demoneeded-1.1-py2.4.egg
163
164Note that we didn't get the newest versions available.  There were
165release candidates for newer versions of both packages. By default,
166final releases are preferred.  We can change this behavior using the
167prefer_final function:
168
169    >>> zc.buildout.easy_install.prefer_final(False)
170    True
171
172The old setting is returned.
173
174    >>> ws = zc.buildout.easy_install.install(
175    ...     ['demo'], dest, links=[link_server], index=link_server+'index/')
176    >>> for dist in ws:
177    ...     print dist
178    demo 0.4c1
179    demoneeded 1.2c1
180
181    >>> ls(dest)
182    -  demo-0.2-py2.4.egg
183    -  demo-0.3-py2.4.egg
184    -  demo-0.4c1-py2.4.egg
185    -  demoneeded-1.1-py2.4.egg
186    -  demoneeded-1.2c1-py2.4.egg
187
188Let's put the setting back to the default.
189
190    >>> zc.buildout.easy_install.prefer_final(True)
191    False
192
193We can supply additional distributions.  We can also supply
194specifications for distributions that would normally be found via
195dependencies.  We might do this to specify a specific version.
196
197    >>> ws = zc.buildout.easy_install.install(
198    ...     ['demo', 'other', 'demoneeded==1.0'], dest,
199    ...     links=[link_server], index=link_server+'index/')
200
201    >>> for dist in ws:
202    ...     print dist
203    demo 0.3
204    other 1.0
205    demoneeded 1.0
206
207    >>> ls(dest)
208    -  demo-0.2-py2.4.egg
209    -  demo-0.3-py2.4.egg
210    -  demo-0.4c1-py2.4.egg
211    -  demoneeded-1.0-py2.4.egg
212    -  demoneeded-1.1-py2.4.egg
213    -  demoneeded-1.2c1-py2.4.egg
214    d  other-1.0-py2.4.egg
215
216We can request that eggs be unzipped even if they are zip safe.  This
217can be useful when debugging.
218
219    >>> rmdir(dest)
220    >>> dest = tmpdir('sample-install')
221    >>> ws = zc.buildout.easy_install.install(
222    ...     ['demo'], dest, links=[link_server], index=link_server+'index/',
223    ...     always_unzip=True)
224
225    >>> ls(dest)
226    d  demo-0.3-py2.4.egg
227    d  demoneeded-1.1-py2.4.egg
228
229    >>> rmdir(dest)
230    >>> dest = tmpdir('sample-install')
231    >>> ws = zc.buildout.easy_install.install(
232    ...     ['demo'], dest, links=[link_server], index=link_server+'index/',
233    ...     always_unzip=False)
234
235    >>> ls(dest)
236    -  demo-0.3-py2.4.egg
237    -  demoneeded-1.1-py2.4.egg
238
239We can also set a default by calling the always_unzip function:
240
241    >>> zc.buildout.easy_install.always_unzip(True)
242    False
243
244The old default is returned:
245
246    >>> rmdir(dest)
247    >>> dest = tmpdir('sample-install')
248    >>> ws = zc.buildout.easy_install.install(
249    ...     ['demo'], dest, links=[link_server], index=link_server+'index/')
250
251    >>> ls(dest)
252    d  demo-0.3-py2.4.egg
253    d  demoneeded-1.1-py2.4.egg
254
255
256    >>> zc.buildout.easy_install.always_unzip(False)
257    True
258
259    >>> rmdir(dest)
260    >>> dest = tmpdir('sample-install')
261    >>> ws = zc.buildout.easy_install.install(
262    ...     ['demo'], dest, links=[link_server], index=link_server+'index/')
263
264    >>> ls(dest)
265    -  demo-0.3-py2.4.egg
266    -  demoneeded-1.1-py2.4.egg
267
268    >>> rmdir(dest)
269    >>> dest = tmpdir('sample-install')
270    >>> ws = zc.buildout.easy_install.install(
271    ...     ['demo'], dest, links=[link_server], index=link_server+'index/',
272    ...     always_unzip=True)
273
274    >>> ls(dest)
275    d  demo-0.3-py2.4.egg
276    d  demoneeded-1.1-py2.4.egg
277
278Specifying version information independent of requirements
279----------------------------------------------------------
280
281Sometimes it's useful to specify version information independent of
282normal requirements specifications.  For example, a buildout may need
283to lock down a set of versions, without having to put put version
284numbers in setup files or part definitions.  If a dictionary is passed
285to the install function, mapping project names to version numbers,
286then the versions numbers will be used.
287
288    >>> ws = zc.buildout.easy_install.install(
289    ...     ['demo'], dest, links=[link_server], index=link_server+'index/',
290    ...     versions = dict(demo='0.2', demoneeded='1.0'))
291    >>> [d.version for d in ws]
292    ['0.2', '1.0']
293
294In this example, we specified a version for demoneeded, even though we
295didn't define a requirement for it.  The versions specified apply to
296dependencies as well as the specified requirements.
297
298If we specify a version that's incompatible with a requirement, then
299we'll get an error:
300
301    >>> from zope.testing.loggingsupport import InstalledHandler
302    >>> handler = InstalledHandler('zc.buildout.easy_install')
303    >>> import logging
304    >>> logging.getLogger('zc.buildout.easy_install').propagate = False
305
306    >>> ws = zc.buildout.easy_install.install(
307    ...     ['demo >0.2'], dest, links=[link_server],
308    ...     index=link_server+'index/',
309    ...     versions = dict(demo='0.2', demoneeded='1.0'))
310    Traceback (most recent call last):
311    ...
312    IncompatibleVersionError: Bad version 0.2
313
314    >>> print handler
315    zc.buildout.easy_install DEBUG
316      Installing 'demo >0.2'.
317    zc.buildout.easy_install ERROR
318      The version, 0.2, is not consistent with the requirement, 'demo>0.2'.
319
320    >>> handler.clear()
321
322If no versions are specified, a debugging message will be output
323reporting that a version was picked automatically:
324
325    >>> ws = zc.buildout.easy_install.install(
326    ...     ['demo'], dest, links=[link_server], index=link_server+'index/',
327    ...     )
328
329    >>> print handler
330    zc.buildout.easy_install DEBUG
331      Installing 'demo'.
332    zc.buildout.easy_install DEBUG
333      We have the best distribution that satisfies 'demo'.
334    zc.buildout.easy_install DEBUG
335      Picked: demo = 0.3
336    zc.buildout.easy_install DEBUG
337      Getting required 'demoneeded'
338    zc.buildout.easy_install DEBUG
339        required by demo 0.3.
340    zc.buildout.easy_install DEBUG
341      We have the best distribution that satisfies 'demoneeded'.
342    zc.buildout.easy_install DEBUG
343      Picked: demoneeded = 1.1
344
345    >>> handler.uninstall()
346    >>> logging.getLogger('zc.buildout.easy_install').propagate = True
347
348We can request that we get an error if versions are picked:
349
350    >>> zc.buildout.easy_install.allow_picked_versions(False)
351    True
352
353(The old setting is returned.)
354
355    >>> ws = zc.buildout.easy_install.install(
356    ...     ['demo'], dest, links=[link_server], index=link_server+'index/',
357    ...     )
358    Traceback (most recent call last):
359    ...
360    UserError: Picked: demo = 0.3
361
362    >>> zc.buildout.easy_install.allow_picked_versions(True)
363    False
364
365The function default_versions can be used to get and set default
366version information to be used when no version information is passes.
367If called with an argument, it sets the default versions:
368
369    >>> zc.buildout.easy_install.default_versions(dict(demoneeded='1'))
370    {}
371
372It always returns the previous default versions.  If called without an
373argument, it simply returns the default versions without changing
374them:
375
376    >>> zc.buildout.easy_install.default_versions()
377    {'demoneeded': '1'}
378
379So with the default versions set, we'll get the requested version even
380if the versions option isn't used:
381
382    >>> ws = zc.buildout.easy_install.install(
383    ...     ['demo'], dest, links=[link_server], index=link_server+'index/',
384    ...     )
385
386    >>> [d.version for d in ws]
387    ['0.3', '1.0']
388
389Of course, we can unset the default versions by passing an empty
390dictionary:
391
392    >>> zc.buildout.easy_install.default_versions({})
393    {'demoneeded': '1'}
394
395    >>> ws = zc.buildout.easy_install.install(
396    ...     ['demo'], dest, links=[link_server], index=link_server+'index/',
397    ...     )
398
399    >>> [d.version for d in ws]
400    ['0.3', '1.1']
401
402Dependency links
403----------------
404
405Setuptools allows metadata that describes where to search for package
406dependencies. This option is called dependency_links. Buildout has its
407own notion of where to look for dependencies, but it also uses the
408setup tools dependency_links information if it's available.
409
410Let's demo this by creating an egg that specifies dependency_links.
411
412To begin, let's create a new egg repository. This repository hold a
413newer version of the 'demoneeded' egg than the sample repository does.
414
415    >>> repoloc = tmpdir('repo')
416    >>> from zc.buildout.tests import create_egg
417    >>> create_egg('demoneeded', '1.2', repoloc)
418    >>> link_server2 = start_server(repoloc)
419
420Turn on logging on this server so that we can see when eggs are pulled
421from it.
422
423    >>> get(link_server2 + 'enable_server_logging')
424    GET 200 /enable_server_logging
425    ''
426
427Now we can create an egg that specifies that its dependencies are
428found on this server.
429
430    >>> repoloc = tmpdir('repo2')
431    >>> create_egg('hasdeps', '1.0', repoloc,
432    ...            install_requires = "'demoneeded'",
433    ...            dependency_links = [link_server2])
434
435Let's add the egg to another repository.
436
437    >>> link_server3 = start_server(repoloc)
438
439Now let's install the egg.
440
441    >>> example_dest = tmpdir('example-install')
442    >>> workingset = zc.buildout.easy_install.install(
443    ...     ['hasdeps'], example_dest,
444    ...     links=[link_server3], index=link_server3+'index/')
445    GET 200 /
446    GET 200 /demoneeded-1.2-pyN.N.egg
447
448The server logs show that the dependency was retrieved from the server
449specified in the dependency_links.
450
451Now let's see what happens if we provide two different ways to retrieve
452the dependencies.
453
454    >>> rmdir(example_dest)
455    >>> example_dest = tmpdir('example-install')
456    >>> workingset = zc.buildout.easy_install.install(
457    ...     ['hasdeps'], example_dest, index=link_server+'index/',
458    ...     links=[link_server, link_server3])
459    GET 200 /
460    GET 200 /demoneeded-1.2-pyN.N.egg
461
462Once again the dependency is fetched from the logging server even
463though it is also available from the non-logging server. This is
464because the version on the logging server is newer and buildout
465normally chooses the newest egg available.
466
467If you wish to control where dependencies come from regardless of
468dependency_links setup metadata use the 'use_dependency_links' option
469to zc.buildout.easy_install.install().
470
471    >>> rmdir(example_dest)
472    >>> example_dest = tmpdir('example-install')
473    >>> workingset = zc.buildout.easy_install.install(
474    ...     ['hasdeps'], example_dest, index=link_server+'index/',
475    ...     links=[link_server, link_server3],
476    ...     use_dependency_links=False)
477
478Notice that this time the dependency egg is not fetched from the
479logging server. When you specify not to use dependency_links, eggs
480will only be searched for using the links you explicitly provide.
481
482Another way to control this option is with the
483zc.buildout.easy_install.use_dependency_links() function. This
484function sets the default behavior for the zc.buildout.easy_install()
485function.
486
487    >>> zc.buildout.easy_install.use_dependency_links(False)
488    True
489
490The function returns its previous setting.
491
492    >>> rmdir(example_dest)
493    >>> example_dest = tmpdir('example-install')
494    >>> workingset = zc.buildout.easy_install.install(
495    ...     ['hasdeps'], example_dest, index=link_server+'index/',
496    ...     links=[link_server, link_server3])
497
498It can be overridden by passing a keyword argument to the install
499function.
500
501    >>> rmdir(example_dest)
502    >>> example_dest = tmpdir('example-install')
503    >>> workingset = zc.buildout.easy_install.install(
504    ...     ['hasdeps'], example_dest, index=link_server+'index/',
505    ...     links=[link_server, link_server3],
506    ...     use_dependency_links=True)
507    GET 200 /demoneeded-1.2-pyN.N.egg
508
509To return the dependency_links behavior to normal call the function again.
510
511    >>> zc.buildout.easy_install.use_dependency_links(True)
512    False
513    >>> rmdir(example_dest)
514    >>> example_dest = tmpdir('example-install')
515    >>> workingset = zc.buildout.easy_install.install(
516    ...     ['hasdeps'], example_dest, index=link_server+'index/',
517    ...     links=[link_server, link_server3])
518    GET 200 /demoneeded-1.2-pyN.N.egg
519
520
521Script generation
522-----------------
523
524The easy_install module provides support for creating scripts from
525eggs.  It provides a function similar to setuptools except that it
526provides facilities for baking a script's path into the script.  This
527has two advantages:
528
529- The eggs to be used by a script are not chosen at run time, making
530  startup faster and, more importantly, deterministic.
531
532- The script doesn't have to import pkg_resources because the logic
533  that pkg_resources would execute at run time is executed at
534  script-creation time.
535
536The scripts method can be used to generate scripts. Let's create a
537destination directory for it to place them in:
538
539    >>> import tempfile
540    >>> bin = tmpdir('bin')
541
542Now, we'll use the scripts method to generate scripts in this directory
543from the demo egg:
544
545    >>> import sys
546    >>> scripts = zc.buildout.easy_install.scripts(
547    ...     ['demo'], ws, sys.executable, bin)
548
549the four arguments we passed were:
550
5511. A sequence of distribution requirements.  These are of the same
552   form as setuptools requirements.  Here we passed a single
553   requirement, for the version 0.1 demo distribution.
554
5552. A working set,
556
5573. The Python executable to use, and
558
5593. The destination directory.
560
561The bin directory now contains a generated script:
562
563    >>> ls(bin)
564    -  demo
565
566The return value is a list of the scripts generated:
567
568    >>> import os, sys
569    >>> if sys.platform == 'win32':
570    ...     scripts == [os.path.join(bin, 'demo.exe'),
571    ...                 os.path.join(bin, 'demo-script.py')]
572    ... else:
573    ...     scripts == [os.path.join(bin, 'demo')]
574    True
575
576Note that in Windows, 2 files are generated for each script.  A script
577file, ending in '-script.py', and an exe file that allows the script
578to be invoked directly without having to specify the Python
579interpreter and without having to provide a '.py' suffix.
580
581The demo script run the entry point defined in the demo egg:
582
583    >>> cat(bin, 'demo') # doctest: +NORMALIZE_WHITESPACE
584    #!/usr/local/bin/python2.4
585    <BLANKLINE>
586    import sys
587    sys.path[0:0] = [
588      '/sample-install/demo-0.3-py2.4.egg',
589      '/sample-install/demoneeded-1.1-py2.4.egg',
590      ]
591    <BLANKLINE>
592    import eggrecipedemo
593    <BLANKLINE>
594    if __name__ == '__main__':
595        eggrecipedemo.main()
596
597Some things to note:
598
599- The demo and demoneeded eggs are added to the beginning of sys.path.
600
601- The module for the script entry point is imported and the entry
602  point, in this case, 'main', is run.
603
604Rather than requirement strings, you can pass tuples containing 3
605strings:
606
607  - A script name,
608
609  - A module,
610
611  - An attribute expression for an entry point within the module.
612
613For example, we could have passed entry point information directly
614rather than passing a requirement:
615
616    >>> scripts = zc.buildout.easy_install.scripts(
617    ...     [('demo', 'eggrecipedemo', 'main')],
618    ...     ws, sys.executable, bin)
619
620    >>> cat(bin, 'demo') # doctest: +NORMALIZE_WHITESPACE
621    #!/usr/local/bin/python2.4
622    <BLANKLINE>
623    import sys
624    sys.path[0:0] = [
625      '/sample-install/demo-0.3-py2.4.egg',
626      '/sample-install/demoneeded-1.1-py2.4.egg',
627      ]
628    <BLANKLINE>
629    import eggrecipedemo
630    <BLANKLINE>
631    if __name__ == '__main__':
632        eggrecipedemo.main()
633
634Passing entry-point information directly is handy when using eggs (or
635distributions) that don't declare their entry points, such as
636distributions that aren't based on setuptools.
637
638The interpreter keyword argument can be used to generate a script that can
639be used to invoke the Python interactive interpreter with the path set
640based on the working set.  This generated script can also be used to
641run other scripts with the path set on the working set:
642
643    >>> scripts = zc.buildout.easy_install.scripts(
644    ...     ['demo'], ws, sys.executable, bin, interpreter='py')
645
646
647    >>> ls(bin)
648    -  demo
649    -  py
650
651    >>> if sys.platform == 'win32':
652    ...     scripts == [os.path.join(bin, 'demo.exe'),
653    ...                 os.path.join(bin, 'demo-script.py'),
654    ...                 os.path.join(bin, 'py.exe'),
655    ...                 os.path.join(bin, 'py-script.py')]
656    ... else:
657    ...     scripts == [os.path.join(bin, 'demo'),
658    ...                 os.path.join(bin, 'py')]
659    True
660
661The py script simply runs the Python interactive interpreter with
662the path set:
663
664    >>> cat(bin, 'py') # doctest: +NORMALIZE_WHITESPACE
665    #!/usr/local/bin/python2.4
666    import sys
667    <BLANKLINE>
668    sys.path[0:0] = [
669      '/sample-install/demo-0.3-py2.4.egg',
670      '/sample-install/demoneeded-1.1-py2.4.egg',
671      ]
672    <BLANKLINE>
673    _interactive = True
674    if len(sys.argv) > 1:
675        import getopt
676        _options, _args = getopt.getopt(sys.argv[1:], 'ic:')
677        _interactive = False
678        for (_opt, _val) in _options:
679            if _opt == '-i':
680                _interactive = True
681            elif _opt == '-c':
682                exec _val
683    <BLANKLINE>
684        if _args:
685            sys.argv[:] = _args
686            execfile(sys.argv[0])
687    <BLANKLINE>
688    if _interactive:
689        import code
690        code.interact(banner="", local=globals())
691
692If invoked with a script name and arguments, it will run that script, instead.
693
694An additional argument can be passed to define which scripts to install
695and to provide script names. The argument is a dictionary mapping
696original script names to new script names.
697
698    >>> bin = tmpdir('bin2')
699    >>> scripts = zc.buildout.easy_install.scripts(
700    ...    ['demo'], ws, sys.executable, bin, dict(demo='run'))
701
702    >>> if sys.platform == 'win32':
703    ...     scripts == [os.path.join(bin, 'run.exe'),
704    ...                 os.path.join(bin, 'run-script.py')]
705    ... else:
706    ...     scripts == [os.path.join(bin, 'run')]
707    True
708    >>> ls(bin)
709    -  run
710
711    >>> print system(os.path.join(bin, 'run')),
712    3 1
713
714Including extra paths in scripts
715--------------------------------
716
717We can pass a keyword argument, extra paths, to cause additional paths
718to be included in the a generated script:
719
720    >>> scripts = zc.buildout.easy_install.scripts(
721    ...    ['demo'], ws, sys.executable, bin, dict(demo='run'),
722    ...    extra_paths=['/foo/bar'])
723
724    >>> cat(bin, 'run') # doctest: +NORMALIZE_WHITESPACE
725    #!/usr/local/bin/python2.4
726    <BLANKLINE>
727    import sys
728    sys.path[0:0] = [
729      '/sample-install/demo-0.3-py2.4.egg',
730      '/sample-install/demoneeded-1.1-py2.4.egg',
731      '/foo/bar',
732      ]
733    <BLANKLINE>
734    import eggrecipedemo
735    <BLANKLINE>
736    if __name__ == '__main__':
737        eggrecipedemo.main()
738
739Providing script arguments
740--------------------------
741
742An "argument" keyword argument can be used to pass arguments to an
743entry point.  The value passed is a source string to be placed between the
744parentheses in the call:
745
746    >>> scripts = zc.buildout.easy_install.scripts(
747    ...    ['demo'], ws, sys.executable, bin, dict(demo='run'),
748    ...    arguments='1, 2')
749
750    >>> cat(bin, 'run') # doctest: +NORMALIZE_WHITESPACE
751    #!/usr/local/bin/python2.4
752    import sys
753    sys.path[0:0] = [
754      '/sample-install/demo-0.3-py2.4.egg',
755      '/sample-install/demoneeded-1.1-py2.4.egg',
756      ]
757    <BLANKLINE>
758    import eggrecipedemo
759    <BLANKLINE>
760    if __name__ == '__main__':
761        eggrecipedemo.main(1, 2)
762
763Passing initialization code
764---------------------------
765
766You can also pass script initialization code:
767
768    >>> scripts = zc.buildout.easy_install.scripts(
769    ...    ['demo'], ws, sys.executable, bin, dict(demo='run'),
770    ...    arguments='1, 2',
771    ...    initialization='import os\nos.chdir("foo")')
772
773    >>> cat(bin, 'run') # doctest: +NORMALIZE_WHITESPACE
774    #!/usr/local/bin/python2.4
775    import sys
776    sys.path[0:0] = [
777      '/sample-install/demo-0.3-py2.4.egg',
778      '/sample-install/demoneeded-1.1-py2.4.egg',
779      ]
780    <BLANKLINE>
781    import os
782    os.chdir("foo")
783    <BLANKLINE>
784    import eggrecipedemo
785    <BLANKLINE>
786    if __name__ == '__main__':
787        eggrecipedemo.main(1, 2)
788
789Relative paths
790--------------
791
792Sometimes, you want to be able to move a buildout directory around and
793have scripts still work without having to rebuild them.  We can
794control this using the relative_paths option to install.  You need
795to pass a common base directory of the scripts and eggs:
796
797    >>> bo = tmpdir('bo')
798    >>> mkdir(bo, 'eggs')
799    >>> mkdir(bo, 'bin')
800    >>> mkdir(bo, 'other')
801
802    >>> ws = zc.buildout.easy_install.install(
803    ...     ['demo'], join(bo, 'eggs'), links=[link_server],
804    ...     index=link_server+'index/')
805
806    >>> scripts = zc.buildout.easy_install.scripts(
807    ...    ['demo'], ws, sys.executable, join(bo, 'bin'), dict(demo='run'),
808    ...    extra_paths=[os.path.sep+'foo', join(bo, 'bar')],
809    ...    interpreter='py',
810    ...    relative_paths=bo)
811
812    >>> cat(bo, 'bin', 'run')
813    #!/usr/local/bin/python2.4
814    <BLANKLINE>
815    import os
816    <BLANKLINE>
817    join = os.path.join
818    base = os.path.dirname(__file__)
819    base = os.path.dirname(base)
820    <BLANKLINE>
821    import sys
822    sys.path[0:0] = [
823      join(base, 'eggs/demo-0.3-pyN.N.egg'),
824      join(base, 'eggs/demoneeded-1.1-pyN.N.egg'),
825      '/foo',
826      join(base, 'bar'),
827      ]
828    <BLANKLINE>
829    import eggrecipedemo
830    <BLANKLINE>
831    if __name__ == '__main__':
832        eggrecipedemo.main()
833
834Note that the extra path we specified that was outside the directory
835passed as relative_paths wasn't converted to a relative path.
836
837Of course, running the script works:
838
839    >>> print system(join(bo, 'bin', 'run')),
840    3 1
841
842We specified an interpreter and its paths are adjusted too:
843
844    >>> cat(bo, 'bin', 'py')
845    #!/usr/local/bin/python2.4
846    <BLANKLINE>
847    import os
848    <BLANKLINE>
849    join = os.path.join
850    base = os.path.dirname(__file__)
851    base = os.path.dirname(base)
852    <BLANKLINE>
853    import sys
854    <BLANKLINE>
855    sys.path[0:0] = [
856      join(base, 'eggs/demo-0.3-pyN.N.egg'),
857      join(base, 'eggs/demoneeded-1.1-pyN.N.egg'),
858      '/foo',
859      join(base, 'bar'),
860      ]
861    <BLANKLINE>
862    _interactive = True
863    if len(sys.argv) > 1:
864        import getopt
865        _options, _args = getopt.getopt(sys.argv[1:], 'ic:')
866        _interactive = False
867        for (_opt, _val) in _options:
868            if _opt == '-i':
869                _interactive = True
870            elif _opt == '-c':
871                exec _val
872    <BLANKLINE>
873        if _args:
874            sys.argv[:] = _args
875            execfile(sys.argv[0])
876    <BLANKLINE>
877    if _interactive:
878        import code
879        code.interact(banner="", local=globals())
880
881
882Handling custom build options for extensions provided in source distributions
883-----------------------------------------------------------------------------
884
885Sometimes, we need to control how extension modules are built.  The
886build function provides this level of control.  It takes a single
887package specification, downloads a source distribution, and builds it
888with specified custom build options.
889
890The build function takes 3 positional arguments:
891
892spec
893   A package specification for a source distribution
894
895dest
896   A destination directory
897
898build_ext
899   A dictionary of options to be passed to the distutils build_ext
900   command when building extensions.
901
902It supports a number of optional keyword arguments:
903
904links
905   a sequence of URLs, file names, or directories to look for
906   links to distributions,
907
908index
909   The URL of an index server, or almost any other valid URL. :)
910
911   If not specified, the Python Package Index,
912   http://pypi.python.org/simple/, is used.  You can specify an
913   alternate index with this option.  If you use the links option and
914   if the links point to the needed distributions, then the index can
915   be anything and will be largely ignored.  In the examples, here,
916   we'll just point to an empty directory on our link server.  This
917   will make our examples run a little bit faster.
918
919executable
920   A path to a Python executable.  Distributions will be installed
921   using this executable and will be for the matching Python version.
922
923path
924   A list of additional directories to search for locally-installed
925   distributions.
926
927newest
928   A boolean value indicating whether to search for new distributions
929   when already-installed distributions meet the requirement.  When
930   this is true, the default, and when the destination directory is
931   not None, then the install function will search for the newest
932   distributions that satisfy the requirements.
933
934versions
935   A dictionary mapping project names to version numbers to be used
936   when selecting distributions.  This can be used to specify a set of
937   distribution versions independent of other requirements.
938
939
940Our link server included a source distribution that includes a simple
941extension, extdemo.c::
942
943  #include <Python.h>
944  #include <extdemo.h>
945
946  static PyMethodDef methods[] = {};
947
948  PyMODINIT_FUNC
949  initextdemo(void)
950  {
951      PyObject *m;
952      m = Py_InitModule3("extdemo", methods, "");
953  #ifdef TWO
954      PyModule_AddObject(m, "val", PyInt_FromLong(2));
955  #else
956      PyModule_AddObject(m, "val", PyInt_FromLong(EXTDEMO));
957  #endif
958  }
959
960The extension depends on a system-dependent include file, extdemo.h,
961that defines a constant, EXTDEMO, that is exposed by the extension.
962
963We'll add an include directory to our sample buildout and add the
964needed include file to it:
965
966    >>> mkdir('include')
967    >>> write('include', 'extdemo.h',
968    ... """
969    ... #define EXTDEMO 42
970    ... """)
971
972Now, we can use the build function to create an egg from the source
973distribution:
974
975    >>> zc.buildout.easy_install.build(
976    ...   'extdemo', dest,
977    ...   {'include-dirs': os.path.join(sample_buildout, 'include')},
978    ...   links=[link_server], index=link_server+'index/')
979    ['/sample-install/extdemo-1.4-py2.4-unix-i686.egg']
980
981The function returns the list of eggs
982
983Now if we look in our destination directory, we see we have an extdemo egg:
984
985    >>> ls(dest)
986    -  demo-0.2-py2.4.egg
987    d  demo-0.3-py2.4.egg
988    -  demoneeded-1.0-py2.4.egg
989    d  demoneeded-1.1-py2.4.egg
990    d  extdemo-1.4-py2.4-unix-i686.egg
991
992Let's update our link server with a new version of extdemo:
993
994    >>> update_extdemo()
995    >>> print get(link_server),
996    <html><body>
997    <a href="bigdemo-0.1-py2.4.egg">bigdemo-0.1-py2.4.egg</a><br>
998    <a href="demo-0.1-py2.4.egg">demo-0.1-py2.4.egg</a><br>
999    <a href="demo-0.2-py2.4.egg">demo-0.2-py2.4.egg</a><br>
1000    <a href="demo-0.3-py2.4.egg">demo-0.3-py2.4.egg</a><br>
1001    <a href="demo-0.4c1-py2.4.egg">demo-0.4c1-py2.4.egg</a><br>
1002    <a href="demoneeded-1.0.zip">demoneeded-1.0.zip</a><br>
1003    <a href="demoneeded-1.1.zip">demoneeded-1.1.zip</a><br>
1004    <a href="demoneeded-1.2c1.zip">demoneeded-1.2c1.zip</a><br>
1005    <a href="extdemo-1.4.zip">extdemo-1.4.zip</a><br>
1006    <a href="extdemo-1.5.zip">extdemo-1.5.zip</a><br>
1007    <a href="index/">index/</a><br>
1008    <a href="other-1.0-py2.4.egg">other-1.0-py2.4.egg</a><br>
1009    </body></html>
1010
1011The easy_install caches information about servers to reduce network
1012access. To see the update, we have to call the clear_index_cache
1013function to clear the index cache:
1014
1015    >>> zc.buildout.easy_install.clear_index_cache()
1016
1017If we run build with newest set to False, we won't get an update:
1018
1019    >>> zc.buildout.easy_install.build(
1020    ...   'extdemo', dest,
1021    ...   {'include-dirs': os.path.join(sample_buildout, 'include')},
1022    ...   links=[link_server], index=link_server+'index/',
1023    ...   newest=False)
1024    ['/sample-install/extdemo-1.4-py2.4-linux-i686.egg']
1025
1026    >>> ls(dest)
1027    -  demo-0.2-py2.4.egg
1028    d  demo-0.3-py2.4.egg
1029    -  demoneeded-1.0-py2.4.egg
1030    d  demoneeded-1.1-py2.4.egg
1031    d  extdemo-1.4-py2.4-unix-i686.egg
1032
1033But if we run it with the default True setting for newest, then we'll
1034get an updated egg:
1035
1036    >>> zc.buildout.easy_install.build(
1037    ...   'extdemo', dest,
1038    ...   {'include-dirs': os.path.join(sample_buildout, 'include')},
1039    ...   links=[link_server], index=link_server+'index/')
1040    ['/sample-install/extdemo-1.5-py2.4-unix-i686.egg']
1041
1042    >>> ls(dest)
1043    -  demo-0.2-py2.4.egg
1044    d  demo-0.3-py2.4.egg
1045    -  demoneeded-1.0-py2.4.egg
1046    d  demoneeded-1.1-py2.4.egg
1047    d  extdemo-1.4-py2.4-unix-i686.egg
1048    d  extdemo-1.5-py2.4-unix-i686.egg
1049
1050The versions option also influences the versions used.  For example,
1051if we specify a version for extdemo, then that will be used, even
1052though it isn't the newest.  Let's clean out the destination directory
1053first:
1054
1055    >>> import os
1056    >>> for name in os.listdir(dest):
1057    ...     remove(dest, name)
1058
1059    >>> zc.buildout.easy_install.build(
1060    ...   'extdemo', dest,
1061    ...   {'include-dirs': os.path.join(sample_buildout, 'include')},
1062    ...   links=[link_server], index=link_server+'index/',
1063    ...   versions=dict(extdemo='1.4'))
1064    ['/sample-install/extdemo-1.4-py2.4-unix-i686.egg']
1065
1066    >>> ls(dest)
1067    d  extdemo-1.4-py2.4-unix-i686.egg
1068
1069Handling custom build options for extensions in develop eggs
1070------------------------------------------------------------
1071
1072The develop function is similar to the build function, except that,
1073rather than building an egg from a source directory containing a
1074setup.py script.
1075
1076The develop function takes 2 positional arguments:
1077
1078setup
1079   The path to a setup script, typically named "setup.py", or a
1080   directory containing a setup.py script.
1081
1082dest
1083   The directory to install the egg link to
1084
1085It supports some optional keyword argument:
1086
1087build_ext
1088   A dictionary of options to be passed to the distutils build_ext
1089   command when building extensions.
1090
1091executable
1092   A path to a Python executable.  Distributions will be installed
1093   using this executable and will be for the matching Python version.
1094
1095We have a local directory containing the extdemo source:
1096
1097    >>> ls(extdemo)
1098    -  MANIFEST
1099    -  MANIFEST.in
1100    -  README
1101    -  extdemo.c
1102    -  setup.py
1103
1104Now, we can use the develop function to create a develop egg from the source
1105distribution:
1106
1107    >>> zc.buildout.easy_install.develop(
1108    ...   extdemo, dest,
1109    ...   {'include-dirs': os.path.join(sample_buildout, 'include')})
1110    '/sample-install/extdemo.egg-link'
1111
1112The name of the egg link created is returned.
1113
1114Now if we look in our destination directory, we see we have an extdemo
1115egg link:
1116
1117    >>> ls(dest)
1118    d  extdemo-1.4-py2.4-unix-i686.egg
1119    -  extdemo.egg-link
1120
1121And that the source directory contains the compiled extension:
1122
1123    >>> ls(extdemo)
1124    -  MANIFEST
1125    -  MANIFEST.in
1126    -  README
1127    d  build
1128    -  extdemo.c
1129    d  extdemo.egg-info
1130    -  extdemo.so
1131    -  setup.py
1132
1133Download cache
1134--------------
1135
1136Normally, when distributions are installed, if any processing is
1137needed, they are downloaded from the internet to a temporary directory
1138and then installed from there.  A download cache can be used to avoid
1139the download step.  This can be useful to reduce network access and to
1140create source distributions of an entire buildout.
1141
1142A download cache is specified by calling the download_cache
1143function.  The function always returns the previous setting. If no
1144argument is passed, then the setting is unchanged.  If an argument is
1145passed, the download cache is set to the given path, which must point
1146to an existing directory.  Passing None clears the cache setting.
1147
1148To see this work, we'll create a directory and set it as the cache
1149directory:
1150
1151    >>> cache = tmpdir('cache')
1152    >>> zc.buildout.easy_install.download_cache(cache)
1153
1154We'll recreate our destination directory:
1155
1156    >>> remove(dest)
1157    >>> dest = tmpdir('sample-install')
1158
1159We'd like to see what is being fetched from the server, so we'll
1160enable server logging:
1161
1162    >>> get(link_server+'enable_server_logging')
1163    GET 200 /enable_server_logging
1164    ''
1165
1166Now, if we install demo, and extdemo:
1167
1168    >>> ws = zc.buildout.easy_install.install(
1169    ...     ['demo==0.2'], dest,
1170    ...     links=[link_server], index=link_server+'index/',
1171    ...     always_unzip=True)
1172    GET 200 /
1173    GET 404 /index/demo/
1174    GET 200 /index/
1175    GET 200 /demo-0.2-py2.4.egg
1176    GET 404 /index/demoneeded/
1177    GET 200 /demoneeded-1.1.zip
1178    GET 404 /index/setuptools/
1179
1180    >>> zc.buildout.easy_install.build(
1181    ...   'extdemo', dest,
1182    ...   {'include-dirs': os.path.join(sample_buildout, 'include')},
1183    ...   links=[link_server], index=link_server+'index/')
1184    GET 404 /index/extdemo/
1185    GET 200 /extdemo-1.5.zip
1186    ['/sample-install/extdemo-1.5-py2.4-linux-i686.egg']
1187
1188Not only will we get eggs in our destination directory:
1189
1190    >>> ls(dest)
1191    d  demo-0.2-py2.4.egg
1192    d  demoneeded-1.1-py2.4.egg
1193    d  extdemo-1.5-py2.4-linux-i686.egg
1194
1195But we'll get distributions in the cache directory:
1196
1197    >>> ls(cache)
1198    -  demo-0.2-py2.4.egg
1199    -  demoneeded-1.1.zip
1200    -  extdemo-1.5.zip
1201
1202The cache directory contains uninstalled distributions, such as zipped
1203eggs or source distributions.
1204
1205Let's recreate our destination directory and clear the index cache:
1206
1207    >>> remove(dest)
1208    >>> dest = tmpdir('sample-install')
1209    >>> zc.buildout.easy_install.clear_index_cache()
1210
1211Now when we install the distributions:
1212
1213    >>> ws = zc.buildout.easy_install.install(
1214    ...     ['demo==0.2'], dest,
1215    ...     links=[link_server], index=link_server+'index/',
1216    ...     always_unzip=True)
1217    GET 200 /
1218    GET 404 /index/demo/
1219    GET 200 /index/
1220    GET 404 /index/demoneeded/
1221    GET 404 /index/setuptools/
1222
1223    >>> zc.buildout.easy_install.build(
1224    ...   'extdemo', dest,
1225    ...   {'include-dirs': os.path.join(sample_buildout, 'include')},
1226    ...   links=[link_server], index=link_server+'index/')
1227    GET 404 /index/extdemo/
1228    ['/sample-install/extdemo-1.5-py2.4-linux-i686.egg']
1229
1230    >>> ls(dest)
1231    d  demo-0.2-py2.4.egg
1232    d  demoneeded-1.1-py2.4.egg
1233    d  extdemo-1.5-py2.4-linux-i686.egg
1234
1235Note that we didn't download the distributions from the link server.
1236
1237If we remove the restriction on demo, we'll download a newer version
1238from the link server:
1239
1240    >>> ws = zc.buildout.easy_install.install(
1241    ...     ['demo'], dest,
1242    ...     links=[link_server], index=link_server+'index/',
1243    ...     always_unzip=True)
1244    GET 200 /demo-0.3-py2.4.egg
1245
1246Normally, the download cache is the preferred source of downloads, but
1247not the only one.
1248
1249Installing solely from a download cache
1250---------------------------------------
1251
1252A download cache can be used as the basis of application source
1253releases.  In an application source release, we want to distribute an
1254application that can be built without making any network accesses.  In
1255this case, we distribute a download cache and tell the easy_install
1256module to install from the download cache only, without making network
1257accesses.  The install_from_cache function can be used to signal that
1258packages should be installed only from the download cache.  The
1259function always returns the previous setting.  Calling it with no
1260arguments returns the current setting without changing it:
1261
1262    >>> zc.buildout.easy_install.install_from_cache()
1263    False
1264
1265Calling it with a boolean value changes the setting and returns the
1266previous setting:
1267
1268    >>> zc.buildout.easy_install.install_from_cache(True)
1269    False
1270
1271Let's remove demo-0.3-py2.4.egg from the cache, clear the index cache,
1272recreate the destination directory, and reinstall demo:
1273
1274    >>> for  f in os.listdir(cache):
1275    ...     if f.startswith('demo-0.3-'):
1276    ...         remove(cache, f)
1277
1278    >>> zc.buildout.easy_install.clear_index_cache()
1279    >>> remove(dest)
1280    >>> dest = tmpdir('sample-install')
1281
1282    >>> ws = zc.buildout.easy_install.install(
1283    ...     ['demo'], dest,
1284    ...     links=[link_server], index=link_server+'index/',
1285    ...     always_unzip=True)
1286
1287    >>> ls(dest)
1288    d  demo-0.2-py2.4.egg
1289    d  demoneeded-1.1-py2.4.egg
1290
1291This time, we didn't download from or even query the link server.
1292
1293.. Disable the download cache:
1294
1295    >>> zc.buildout.easy_install.download_cache(None)
1296    '/cache'
1297
1298    >>> zc.buildout.easy_install.install_from_cache(False)
1299    True
Note: See TracBrowser for help on using the repository browser.