/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to setup.py

  • Committer: Vincent Ladeuil
  • Date: 2012-01-18 14:09:19 UTC
  • mto: This revision was merged to the branch mainline in revision 6468.
  • Revision ID: v.ladeuil+lp@free.fr-20120118140919-rlvdrhpc0nq1lbwi
Change set/remove to require a lock for the branch config files.

This means that tests (or any plugin for that matter) do not requires an
explicit lock on the branch anymore to change a single option. This also
means the optimisation becomes "opt-in" and as such won't be as
spectacular as it may be and/or harder to get right (nothing fails
anymore).

This reduces the diff by ~300 lines.

Code/tests that were updating more than one config option is still taking
a lock to at least avoid some IOs and demonstrate the benefits through
the decreased number of hpss calls.

The duplication between BranchStack and BranchOnlyStack will be removed
once the same sharing is in place for local config files, at which point
the Stack class itself may be able to host the changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
import os
10
10
import os.path
11
11
import sys
 
12
import copy
 
13
import glob
12
14
 
13
 
if sys.version_info < (2, 4):
14
 
    sys.stderr.write("[ERROR] Not a supported Python version. Need 2.4+\n")
 
15
if sys.version_info < (2, 6):
 
16
    sys.stderr.write("[ERROR] Not a supported Python version. Need 2.6+\n")
15
17
    sys.exit(1)
16
18
 
17
19
# NOTE: The directory containing setup.py, whether run by 'python setup.py' or
65
67
            'package_data': {'bzrlib': ['doc/api/*.txt',
66
68
                                        'tests/test_patches_data/*',
67
69
                                        'help_topics/en/*.txt',
 
70
                                        'tests/ssl_certs/ca.crt',
68
71
                                        'tests/ssl_certs/server_without_pass.key',
69
72
                                        'tests/ssl_certs/server_with_pass.key',
70
 
                                        'tests/ssl_certs/server.crt'
 
73
                                        'tests/ssl_certs/server.crt',
71
74
                                       ]},
72
75
           }
73
 
 
 
76
I18N_FILES = []
 
77
for filepath in glob.glob("bzrlib/locale/*/LC_MESSAGES/*.mo"):
 
78
    langfile = filepath[len("bzrlib/locale/"):]
 
79
    targetpath = os.path.dirname(os.path.join("share/locale", langfile))
 
80
    I18N_FILES.append((targetpath, [filepath]))
74
81
 
75
82
def get_bzrlib_packages():
76
83
    """Recurse through the bzrlib directory, and extract the package names"""
125
132
                f = file(batch_path, "w")
126
133
                f.write(batch_str)
127
134
                f.close()
128
 
                print "Created:", batch_path
129
 
            except Exception, e:
130
 
                print "ERROR: Unable to create %s: %s" % (batch_path, e)
 
135
                print("Created: %s" % batch_path)
 
136
            except Exception:
 
137
                e = sys.exc_info()[1]
 
138
                print("ERROR: Unable to create %s: %s" % (batch_path, e))
131
139
 
132
140
    def _quoted_path(self, path):
133
141
        if ' ' in path:
149
157
    Generate bzr.1.
150
158
    """
151
159
 
 
160
    sub_commands = build.sub_commands + [
 
161
            ('build_mo', lambda _: True),
 
162
            ]
 
163
 
152
164
    def run(self):
153
165
        build.run(self)
154
166
 
160
172
## Setup
161
173
########################
162
174
 
 
175
from bzrlib.bzr_distutils import build_mo
 
176
 
163
177
command_classes = {'install_scripts': my_install_scripts,
164
 
                   'build': bzr_build}
 
178
                   'build': bzr_build,
 
179
                   'build_mo': build_mo,
 
180
                   }
165
181
from distutils import log
166
182
from distutils.errors import CCompilerError, DistutilsPlatformError
167
183
from distutils.extension import Extension
168
184
ext_modules = []
169
185
try:
170
186
    try:
 
187
        from Cython.Distutils import build_ext
 
188
        from Cython.Compiler.Version import version as pyrex_version
 
189
    except ImportError:
 
190
        print("No Cython, trying Pyrex...")
171
191
        from Pyrex.Distutils import build_ext
172
192
        from Pyrex.Compiler.Version import version as pyrex_version
173
 
    except ImportError:
174
 
        print "No Pyrex, trying Cython..."
175
 
        from Cython.Distutils import build_ext
176
 
        from Cython.Compiler.Version import version as pyrex_version
177
193
except ImportError:
178
194
    have_pyrex = False
179
195
    # try to build the extension from the prior generated source.
180
 
    print
181
 
    print ("The python package 'Pyrex' is not available."
182
 
           " If the .c files are available,")
183
 
    print ("they will be built,"
184
 
           " but modifying the .pyx files will not rebuild them.")
185
 
    print
 
196
    print("")
 
197
    print("The python package 'Pyrex' is not available."
 
198
          " If the .c files are available,")
 
199
    print("they will be built,"
 
200
          " but modifying the .pyx files will not rebuild them.")
 
201
    print("")
186
202
    from distutils.command.build_ext import build_ext
187
203
else:
188
204
    have_pyrex = True
189
 
    pyrex_version_info = tuple(map(int, pyrex_version.split('.')))
 
205
    pyrex_version_info = tuple(map(int, pyrex_version.rstrip("+").split('.')))
190
206
 
191
207
 
192
208
class build_ext_if_possible(build_ext):
204
220
    def run(self):
205
221
        try:
206
222
            build_ext.run(self)
207
 
        except DistutilsPlatformError, e:
 
223
        except DistutilsPlatformError:
 
224
            e = sys.exc_info()[1]
208
225
            if not self.allow_python_fallback:
209
226
                log.warn('\n  Cannot build extensions.\n'
210
227
                         '  Use "build_ext --allow-python-fallback" to use'
281
298
    add_pyrex_extension('bzrlib._dirstate_helpers_pyx',
282
299
                        libraries=['Ws2_32'])
283
300
    add_pyrex_extension('bzrlib._walkdirs_win32')
284
 
    z_lib = 'zdll'
285
301
else:
286
302
    if have_pyrex and pyrex_version_info[:3] == (0,9,4):
287
303
        # Pyrex 0.9.4.1 fails to compile this extension correctly
288
304
        # The code it generates re-uses a "local" pointer and
289
305
        # calls "PY_DECREF" after having set it to NULL. (It mixes PY_XDECREF
290
306
        # which is NULL safe with PY_DECREF which is not.)
291
 
        # <https://bugs.edge.launchpad.net/bzr/+bug/449372>
292
 
        # <https://bugs.edge.launchpad.net/bzr/+bug/276868>
293
 
        print 'Cannot build extension "bzrlib._dirstate_helpers_pyx" using'
294
 
        print 'your version of pyrex "%s". Please upgrade your pyrex' % (
295
 
            pyrex_version,)
296
 
        print 'install. For now, the non-compiled (python) version will'
297
 
        print 'be used instead.'
 
307
        # <https://bugs.launchpad.net/bzr/+bug/449372>
 
308
        # <https://bugs.launchpad.net/bzr/+bug/276868>
 
309
        print('Cannot build extension "bzrlib._dirstate_helpers_pyx" using')
 
310
        print('your version of pyrex "%s". Please upgrade your pyrex'
 
311
              % (pyrex_version,))
 
312
        print('install. For now, the non-compiled (python) version will')
 
313
        print('be used instead.')
298
314
    else:
299
315
        add_pyrex_extension('bzrlib._dirstate_helpers_pyx')
300
316
    add_pyrex_extension('bzrlib._readdir_pyx')
301
 
    z_lib = 'z'
302
 
add_pyrex_extension('bzrlib._chk_map_pyx', libraries=[z_lib])
 
317
add_pyrex_extension('bzrlib._chk_map_pyx')
303
318
ext_modules.append(Extension('bzrlib._patiencediff_c',
304
319
                             ['bzrlib/_patiencediff_c.c']))
305
320
if have_pyrex and pyrex_version_info < (0, 9, 6, 3):
306
 
    print
307
 
    print 'Your Pyrex/Cython version %s is too old to build the simple_set' % (
308
 
        pyrex_version)
309
 
    print 'and static_tuple extensions.'
310
 
    print 'Please upgrade to at least Pyrex 0.9.6.3'
311
 
    print
 
321
    print("")
 
322
    print('Your Pyrex/Cython version %s is too old to build the simple_set' % (
 
323
        pyrex_version))
 
324
    print('and static_tuple extensions.')
 
325
    print('Please upgrade to at least Pyrex 0.9.6.3')
 
326
    print("")
312
327
    # TODO: Should this be a fatal error?
313
328
else:
314
329
    # We only need 0.9.6.3 to build _simple_set_pyx, but static_tuple depends
320
335
 
321
336
 
322
337
if unavailable_files:
323
 
    print 'C extension(s) not found:'
324
 
    print '   %s' % ('\n  '.join(unavailable_files),)
325
 
    print 'The python versions will be used instead.'
326
 
    print
 
338
    print('C extension(s) not found:')
 
339
    print('   %s' % ('\n  '.join(unavailable_files),))
 
340
    print('The python versions will be used instead.')
 
341
    print("")
327
342
 
328
343
 
329
344
def get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
393
408
    # ditto for the tbzrcommand tool
394
409
    tbzrcommand = dict(
395
410
        script = os.path.join(tbzr_root, "scripts", "tbzrcommand.py"),
396
 
        icon_resources = [(0,'bzr.ico')],
 
411
        icon_resources = icon_resources,
 
412
        other_resources = other_resources,
397
413
    )
398
414
    console_targets.append(tbzrcommand)
399
415
    tbzrcommandw = tbzrcommand.copy()
413
429
 
414
430
def get_qbzr_py2exe_info(includes, excludes, packages, data_files):
415
431
    # PyQt4 itself still escapes the plugin detection code for some reason...
416
 
    packages.append('PyQt4')
417
 
    excludes.append('PyQt4.elementtree.ElementTree')
418
 
    excludes.append('PyQt4.uic.port_v3')
 
432
    includes.append('PyQt4.QtCore')
 
433
    includes.append('PyQt4.QtGui')
419
434
    includes.append('sip') # extension module required for Qt.
420
435
    packages.append('pygments') # colorizer for qbzr
421
436
    packages.append('docutils') # html formatting
422
437
    includes.append('win32event')  # for qsubprocess stuff
423
 
    # but we can avoid many Qt4 Dlls.
424
 
    dll_excludes.extend(
425
 
        """QtAssistantClient4.dll QtCLucene4.dll QtDesigner4.dll
426
 
        QtHelp4.dll QtNetwork4.dll QtOpenGL4.dll QtScript4.dll
427
 
        QtSql4.dll QtTest4.dll QtWebKit4.dll QtXml4.dll
428
 
        qscintilla2.dll""".split())
429
438
    # the qt binaries might not be on PATH...
430
439
    # They seem to install to a place like C:\Python25\PyQt4\*
431
440
    # Which is not the same as C:\Python25\Lib\site-packages\PyQt4
473
482
    packages.append('sqlite3')
474
483
 
475
484
 
 
485
def get_git_py2exe_info(includes, excludes, packages):
 
486
    packages.append('dulwich')
 
487
 
 
488
 
 
489
def get_fastimport_py2exe_info(includes, excludes, packages):
 
490
    # This is the python-fastimport package, not to be confused with the
 
491
    # bzr-fastimport plugin.
 
492
    packages.append('fastimport')
 
493
 
 
494
 
476
495
if 'bdist_wininst' in sys.argv:
477
496
    def find_docs():
478
497
        docs = []
497
516
            # help pages
498
517
            'data_files': find_docs(),
499
518
            # for building pyrex extensions
500
 
            'cmdclass': {'build_ext': build_ext_if_possible},
 
519
            'cmdclass': command_classes,
501
520
           }
502
521
 
503
522
    ARGS.update(META_INFO)
504
523
    ARGS.update(BZRLIB)
 
524
    PKG_DATA['package_data']['bzrlib'].append('locale/*/LC_MESSAGES/*.mo')
505
525
    ARGS.update(PKG_DATA)
506
 
    
 
526
 
507
527
    setup(**ARGS)
508
528
 
509
529
elif 'py2exe' in sys.argv:
510
 
    import glob
511
530
    # py2exe setup
512
531
    import py2exe
513
532
 
534
553
            install_data.run(self)
535
554
 
536
555
            py2exe = self.distribution.get_command_obj('py2exe', False)
537
 
            optimize = py2exe.optimize
 
556
            # GZ 2010-04-19: Setup has py2exe.optimize as 2, but give plugins
 
557
            #                time before living with docstring stripping
 
558
            optimize = 1
538
559
            compile_names = [f for f in self.outfiles if f.endswith('.py')]
 
560
            # Round mtime to nearest even second so that installing on a FAT
 
561
            # filesystem bytecode internal and script timestamps will match
 
562
            for f in compile_names:
 
563
                mtime = os.stat(f).st_mtime
 
564
                remainder = mtime % 2
 
565
                if remainder:
 
566
                    mtime -= remainder
 
567
                    os.utime(f, (mtime, mtime))
539
568
            byte_compile(compile_names,
540
569
                         optimize=optimize,
541
570
                         force=self.force, prefix=self.install_dir,
542
571
                         dry_run=self.dry_run)
543
 
            if optimize:
544
 
                suffix = 'o'
545
 
            else:
546
 
                suffix = 'c'
547
 
            self.outfiles.extend([f + suffix for f in compile_names])
 
572
            self.outfiles.extend([f + 'o' for f in compile_names])
548
573
    # end of class install_data_with_bytecompile
549
574
 
550
575
    target = py2exe.build_exe.Target(script = "bzr",
558
583
                                     company_name = "Canonical Ltd.",
559
584
                                     comments = META_INFO['description'],
560
585
                                    )
 
586
    gui_target = copy.copy(target)
 
587
    gui_target.dest_base = "bzrw"
561
588
 
562
589
    packages = BZRLIB['packages']
563
590
    packages.remove('bzrlib')
648
675
    console_targets = [target,
649
676
                       'tools/win32/bzr_postinstall.py',
650
677
                       ]
651
 
    gui_targets = []
652
 
    data_files = topics_files + plugins_files
 
678
    gui_targets = [gui_target]
 
679
    data_files = topics_files + plugins_files + I18N_FILES
653
680
 
654
681
    if 'qbzr' in plugins:
655
682
        get_qbzr_py2exe_info(includes, excludes, packages, data_files)
657
684
    if 'svn' in plugins:
658
685
        get_svn_py2exe_info(includes, excludes, packages)
659
686
 
 
687
    if 'git' in plugins:
 
688
        get_git_py2exe_info(includes, excludes, packages)
 
689
 
 
690
    if 'fastimport' in plugins:
 
691
        get_fastimport_py2exe_info(includes, excludes, packages)
 
692
 
660
693
    if "TBZR" in os.environ:
661
694
        # TORTOISE_OVERLAYS_MSI_WIN32 must be set to the location of the
662
695
        # TortoiseOverlays MSI installer file. It is in the TSVN svn repo and
681
714
        # print this warning to stderr as output is redirected, so it is seen
682
715
        # at build time.  Also to stdout so it appears in the log
683
716
        for f in (sys.stderr, sys.stdout):
684
 
            print >> f, \
685
 
                "Skipping TBZR binaries - please set TBZR to a directory to enable"
 
717
            f.write("Skipping TBZR binaries - "
 
718
                "please set TBZR to a directory to enable\n")
686
719
 
687
720
    # MSWSOCK.dll is a system-specific library, which py2exe accidentally pulls
688
721
    # in on Vista.
689
 
    dll_excludes.extend(["MSWSOCK.dll", "MSVCP60.dll", "powrprof.dll"])
 
722
    dll_excludes.extend(["MSWSOCK.dll",
 
723
                         "MSVCP60.dll",
 
724
                         "MSVCP90.dll",
 
725
                         "powrprof.dll",
 
726
                         "SHFOLDER.dll"])
690
727
    options_list = {"py2exe": {"packages": packages + list(additional_packages),
691
728
                               "includes": includes,
692
729
                               "excludes": excludes,
693
730
                               "dll_excludes": dll_excludes,
694
731
                               "dist_dir": "win32_bzr.exe",
695
 
                               "optimize": 1,
 
732
                               "optimize": 2,
 
733
                               "custom_boot_script":
 
734
                                        "tools/win32/py2exe_boot_common.py",
696
735
                              },
697
736
                   }
698
737
 
699
 
    setup(options=options_list,
700
 
          console=console_targets,
701
 
          windows=gui_targets,
702
 
          zipfile='lib/library.zip',
703
 
          data_files=data_files,
704
 
          cmdclass={'install_data': install_data_with_bytecompile},
705
 
          )
 
738
    # We want the libaray.zip to have optimize = 2, but the exe to have
 
739
    # optimize = 1, so that .py files that get compilied at run time
 
740
    # (e.g. user installed plugins) dont have their doc strings removed.
 
741
    class py2exe_no_oo_exe(py2exe.build_exe.py2exe):
 
742
        def build_executable(self, *args, **kwargs):
 
743
            self.optimize = 1
 
744
            py2exe.build_exe.py2exe.build_executable(self, *args, **kwargs)
 
745
            self.optimize = 2
 
746
 
 
747
    if __name__ == '__main__':
 
748
        command_classes['install_data'] = install_data_with_bytecompile
 
749
        command_classes['py2exe'] = py2exe_no_oo_exe
 
750
        setup(options=options_list,
 
751
              console=console_targets,
 
752
              windows=gui_targets,
 
753
              zipfile='lib/library.zip',
 
754
              data_files=data_files,
 
755
              cmdclass=command_classes,
 
756
              )
706
757
 
707
758
else:
708
759
    # ad-hoc for easy_install
712
763
        # easy_install one
713
764
        DATA_FILES = [('man/man1', ['bzr.1'])]
714
765
 
715
 
    if sys.platform != 'win32':
716
 
        # see https://wiki.kubuntu.org/Apport/DeveloperHowTo
717
 
        #
718
 
        # checking the paths and hardcoding the check for root is a bit gross,
719
 
        # but I don't see a cleaner way to find out the locations in a way
720
 
        # that's going to align with the hardcoded paths in apport.
721
 
        if os.geteuid() == 0:
722
 
            DATA_FILES += [
723
 
                ('/usr/share/apport/package-hooks',
724
 
                    ['apport/source_bzr.py']),
725
 
                ('/etc/apport/crashdb.conf.d/',
726
 
                    ['apport/bzr-crashdb.conf']),]
727
 
 
 
766
    DATA_FILES = DATA_FILES + I18N_FILES
728
767
    # std setup
729
768
    ARGS = {'scripts': ['bzr'],
730
769
            'data_files': DATA_FILES,
736
775
    ARGS.update(BZRLIB)
737
776
    ARGS.update(PKG_DATA)
738
777
 
739
 
    setup(**ARGS)
 
778
    if __name__ == '__main__':
 
779
        setup(**ARGS)