~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to setup.py

  • Committer: Martin Pool
  • Date: 2005-05-03 08:00:27 UTC
  • Revision ID: mbp@sourcefrog.net-20050503080027-908edb5b39982198
doc

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#! /usr/bin/env python
2
2
 
3
 
"""Installation script for bzr.
4
 
Run it with
5
 
 './setup.py install', or
6
 
 './setup.py --help' for more options
7
 
"""
8
 
 
9
 
import os
10
 
import sys
11
 
 
12
 
import bzrlib
13
 
 
14
 
##
15
 
# META INFORMATION FOR SETUP
16
 
 
17
 
META_INFO = {'name':         'bzr',
18
 
             'version':      bzrlib.__version__,
19
 
             'author':       'Canonical Ltd',
20
 
             'author_email': 'bazaar@lists.canonical.com',
21
 
             'url':          'http://www.bazaar-vcs.org/',
22
 
             'description':  'Friendly distributed version control system',
23
 
             'license':      'GNU GPL v2',
24
 
            }
25
 
 
26
 
# The list of packages is automatically generated later. Add other things
27
 
# that are part of BZRLIB here.
28
 
BZRLIB = {}
29
 
 
30
 
PKG_DATA = {# install files from selftest suite
31
 
            'package_data': {'bzrlib': ['doc/api/*.txt',
32
 
                                        'tests/test_patches_data/*',
33
 
                                       ]},
34
 
           }
35
 
 
36
 
######################################################################
37
 
# Reinvocation stolen from bzr, we need python2.4 by virtue of bzr_man
38
 
# including bzrlib.help
39
 
 
40
 
try:
41
 
    version_info = sys.version_info
42
 
except AttributeError:
43
 
    version_info = 1, 5 # 1.5 or older
44
 
 
45
 
REINVOKE = "__BZR_REINVOKE"
46
 
NEED_VERS = (2, 4)
47
 
KNOWN_PYTHONS = ('python2.4',)
48
 
 
49
 
if version_info < NEED_VERS:
50
 
    if not os.environ.has_key(REINVOKE):
51
 
        # mutating os.environ doesn't work in old Pythons
52
 
        os.putenv(REINVOKE, "1")
53
 
        for python in KNOWN_PYTHONS:
54
 
            try:
55
 
                os.execvp(python, [python] + sys.argv)
56
 
            except OSError:
57
 
                pass
58
 
    sys.stderr.write("bzr: error: cannot find a suitable python interpreter\n")
59
 
    sys.stderr.write("  (need %d.%d or later)" % NEED_VERS)
60
 
    sys.stderr.write('\n')
61
 
    sys.exit(1)
62
 
if getattr(os, "unsetenv", None) is not None:
63
 
    os.unsetenv(REINVOKE)
64
 
 
65
 
 
66
 
def get_bzrlib_packages():
67
 
    """Recurse through the bzrlib directory, and extract the package names"""
68
 
 
69
 
    packages = []
70
 
    base_path = os.path.dirname(os.path.abspath(bzrlib.__file__))
71
 
    for root, dirs, files in os.walk(base_path):
72
 
        if '__init__.py' in files:
73
 
            assert root.startswith(base_path)
74
 
            # Get just the path below bzrlib
75
 
            package_path = root[len(base_path):]
76
 
            # Remove leading and trailing slashes
77
 
            package_path = package_path.strip('\\/')
78
 
            if not package_path:
79
 
                package_name = 'bzrlib'
80
 
            else:
81
 
                package_name = ('bzrlib.' +
82
 
                            package_path.replace('/', '.').replace('\\', '.'))
83
 
            packages.append(package_name)
84
 
    return sorted(packages)
85
 
 
86
 
 
87
 
BZRLIB['packages'] = get_bzrlib_packages()
88
 
 
 
3
# This is an installation script for bzr.  Run it with
 
4
# './setup.py install', or
 
5
# './setup.py --help' for more options
89
6
 
90
7
from distutils.core import setup
91
 
from distutils.command.install_scripts import install_scripts
92
 
from distutils.command.build import build
93
 
 
94
 
###############################
95
 
# Overridden distutils actions
96
 
###############################
97
 
 
98
 
class my_install_scripts(install_scripts):
99
 
    """ Customized install_scripts distutils action.
100
 
    Create bzr.bat for win32.
101
 
    """
102
 
    def run(self):
103
 
        install_scripts.run(self)   # standard action
104
 
 
105
 
        if sys.platform == "win32":
106
 
            try:
107
 
                scripts_dir = os.path.join(sys.prefix, 'Scripts')
108
 
                script_path = self._quoted_path(os.path.join(scripts_dir,
109
 
                                                             "bzr"))
110
 
                python_exe = self._quoted_path(sys.executable)
111
 
                args = self._win_batch_args()
112
 
                batch_str = "@%s %s %s" % (python_exe, script_path, args)
113
 
                batch_path = os.path.join(self.install_dir, "bzr.bat")
114
 
                f = file(batch_path, "w")
115
 
                f.write(batch_str)
116
 
                f.close()
117
 
                print "Created:", batch_path
118
 
            except Exception, e:
119
 
                print "ERROR: Unable to create %s: %s" % (batch_path, e)
120
 
 
121
 
    def _quoted_path(self, path):
122
 
        if ' ' in path:
123
 
            return '"' + path + '"'
124
 
        else:
125
 
            return path
126
 
 
127
 
    def _win_batch_args(self):
128
 
        from bzrlib.win32utils import winver
129
 
        if winver == 'Windows NT':
130
 
            return '%*'
131
 
        else:
132
 
            return '%1 %2 %3 %4 %5 %6 %7 %8 %9'
133
 
#/class my_install_scripts
134
 
 
135
 
 
136
 
class bzr_build(build):
137
 
    """Customized build distutils action.
138
 
    Generate bzr.1.
139
 
    """
140
 
    def run(self):
141
 
        build.run(self)
142
 
 
143
 
        import generate_docs
144
 
        generate_docs.main(argv=["bzr", "man"])
145
 
 
146
 
 
147
 
########################
148
 
## Setup
149
 
########################
150
 
 
151
 
command_classes = {'install_scripts': my_install_scripts,
152
 
                   'build': bzr_build}
153
 
from distutils import log
154
 
from distutils.errors import CCompilerError, DistutilsPlatformError
155
 
from distutils.extension import Extension
156
 
ext_modules = []
157
 
try:
158
 
    from Pyrex.Distutils import build_ext
159
 
except ImportError:
160
 
    have_pyrex = False
161
 
    # try to build the extension from the prior generated source.
162
 
    print
163
 
    print ("The python package 'Pyrex' is not available."
164
 
           " If the .c files are available,")
165
 
    print ("they will be built,"
166
 
           " but modifying the .pyx files will not rebuild them.")
167
 
    print
168
 
    from distutils.command.build_ext import build_ext
169
 
else:
170
 
    have_pyrex = True
171
 
 
172
 
 
173
 
class build_ext_if_possible(build_ext):
174
 
 
175
 
    def run(self):
176
 
        try:
177
 
            build_ext.run(self)
178
 
        except DistutilsPlatformError, e:
179
 
            log.warn(str(e))
180
 
            log.warn('Extensions cannot be built, '
181
 
                     'will use the Python versions instead')
182
 
 
183
 
    def build_extension(self, ext):
184
 
        try:
185
 
            build_ext.build_extension(self, ext)
186
 
        except CCompilerError:
187
 
            log.warn('Building of "%s" extension failed, '
188
 
                     'will use the Python version instead' % (ext.name,))
189
 
 
190
 
 
191
 
# Override the build_ext if we have Pyrex available
192
 
command_classes['build_ext'] = build_ext_if_possible
193
 
unavailable_files = []
194
 
 
195
 
 
196
 
def add_pyrex_extension(module_name, **kwargs):
197
 
    """Add a pyrex module to build.
198
 
 
199
 
    This will use Pyrex to auto-generate the .c file if it is available.
200
 
    Otherwise it will fall back on the .c file. If the .c file is not
201
 
    available, it will warn, and not add anything.
202
 
 
203
 
    You can pass any extra options to Extension through kwargs. One example is
204
 
    'libraries = []'.
205
 
 
206
 
    :param module_name: The python path to the module. This will be used to
207
 
        determine the .pyx and .c files to use.
208
 
    """
209
 
    path = module_name.replace('.', '/')
210
 
    pyrex_name = path + '.pyx'
211
 
    c_name = path + '.c'
212
 
    if have_pyrex:
213
 
        ext_modules.append(Extension(module_name, [pyrex_name]))
214
 
    else:
215
 
        if not os.path.isfile(c_name):
216
 
            unavailable_files.append(c_name)
217
 
        else:
218
 
            ext_modules.append(Extension(module_name, [c_name]))
219
 
 
220
 
 
221
 
add_pyrex_extension('bzrlib._dirstate_helpers_c')
222
 
add_pyrex_extension('bzrlib._knit_load_data_c')
223
 
ext_modules.append(Extension('bzrlib._patiencediff_c', ['bzrlib/_patiencediff_c.c']))
224
 
 
225
 
 
226
 
if unavailable_files:
227
 
    print 'C extension(s) not found:'
228
 
    print '   %s' % ('\n  '.join(unavailable_files),)
229
 
    print 'The python versions will be used instead.'
230
 
    print
231
 
 
232
 
 
233
 
if 'bdist_wininst' in sys.argv:
234
 
    def find_docs():
235
 
        docs = []
236
 
        for root, dirs, files in os.walk('doc'):
237
 
            r = []
238
 
            for f in files:
239
 
                if os.path.splitext(f)[1] in ('.html', '.css'):
240
 
                    r.append(os.path.join(root, f))
241
 
            if r:
242
 
                relative = root[4:]
243
 
                if relative:
244
 
                    target = os.path.join('Doc\\Bazaar', relative)
245
 
                else:
246
 
                    target = 'Doc\\Bazaar'
247
 
                docs.append((target, r))
248
 
        return docs
249
 
 
250
 
    # python's distutils-based win32 installer
251
 
    ARGS = {'scripts': ['bzr', 'tools/win32/bzr-win32-bdist-postinstall.py'],
252
 
            'ext_modules': ext_modules,
253
 
            # help pages
254
 
            'data_files': find_docs(),
255
 
            # for building pyrex extensions
256
 
            'cmdclass': {'build_ext': build_ext_if_possible},
257
 
           }
258
 
 
259
 
    ARGS.update(META_INFO)
260
 
    ARGS.update(BZRLIB)
261
 
    ARGS.update(PKG_DATA)
262
 
    
263
 
    setup(**ARGS)
264
 
 
265
 
elif 'py2exe' in sys.argv:
266
 
    # py2exe setup
267
 
    import py2exe
268
 
 
269
 
    # pick real bzr version
270
 
    import bzrlib
271
 
 
272
 
    version_number = []
273
 
    for i in bzrlib.version_info[:4]:
274
 
        try:
275
 
            i = int(i)
276
 
        except ValueError:
277
 
            i = 0
278
 
        version_number.append(str(i))
279
 
    version_str = '.'.join(version_number)
280
 
 
281
 
    target = py2exe.build_exe.Target(script = "bzr",
282
 
                                     dest_base = "bzr",
283
 
                                     icon_resources = [(0,'bzr.ico')],
284
 
                                     name = META_INFO['name'],
285
 
                                     version = version_str,
286
 
                                     description = META_INFO['description'],
287
 
                                     author = META_INFO['author'],
288
 
                                     copyright = "(c) Canonical Ltd, 2005-2007",
289
 
                                     company_name = "Canonical Ltd.",
290
 
                                     comments = META_INFO['description'],
291
 
                                    )
292
 
 
293
 
    additional_packages =  []
294
 
    if sys.version.startswith('2.4'):
295
 
        # adding elementtree package
296
 
        additional_packages.append('elementtree')
297
 
    elif sys.version.startswith('2.5'):
298
 
        additional_packages.append('xml.etree')
299
 
    else:
300
 
        import warnings
301
 
        warnings.warn('Unknown Python version.\n'
302
 
                      'Please check setup.py script for compatibility.')
303
 
    # email package from std python library use lazy import,
304
 
    # so we need to explicitly add all package
305
 
    additional_packages.append('email')
306
 
 
307
 
    options_list = {"py2exe": {"packages": BZRLIB['packages'] +
308
 
                                           additional_packages,
309
 
                               "excludes": ["Tkinter", "medusa", "tools"],
310
 
                               "dist_dir": "win32_bzr.exe",
311
 
                              },
312
 
                   }
313
 
    setup(options=options_list,
314
 
          console=[target,
315
 
                   'tools/win32/bzr_postinstall.py',
316
 
                  ],
317
 
          zipfile='lib/library.zip')
318
 
 
319
 
else:
320
 
    # ad-hoc for easy_install
321
 
    DATA_FILES = []
322
 
    if not 'bdist_egg' in sys.argv:
323
 
        # generate and install bzr.1 only with plain install, not easy_install one
324
 
        DATA_FILES = [('man/man1', ['bzr.1'])]
325
 
 
326
 
    # std setup
327
 
    ARGS = {'scripts': ['bzr'],
328
 
            'data_files': DATA_FILES,
329
 
            'cmdclass': command_classes,
330
 
            'ext_modules': ext_modules,
331
 
           }
332
 
 
333
 
    ARGS.update(META_INFO)
334
 
    ARGS.update(BZRLIB)
335
 
    ARGS.update(PKG_DATA)
336
 
 
337
 
    setup(**ARGS)
 
8
 
 
9
setup(name='bzr',
 
10
      version='0.0.0',
 
11
      author='Martin Pool',
 
12
      author_email='mbp@sourcefrog.net',
 
13
      url='http://www.bazaar-ng.org/',
 
14
      description='Friendly distributed version control system',
 
15
      license='GNU GPL v2',
 
16
      packages=['bzrlib'],
 
17
      scripts=['bzr'])