| # |
| # |
| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| # |
| # |
| import os |
| import sys |
| import shutil |
| import getopt |
| try: |
| my_getopt = getopt.gnu_getopt |
| except AttributeError: |
| my_getopt = getopt.getopt |
| import glob |
| import traceback |
| try: |
| # Python >=3.0 |
| import configparser |
| except ImportError: |
| # Python <3.0 |
| import ConfigParser as configparser |
| |
| # The script directory and the source base directory |
| _scriptdir = os.path.dirname(sys.argv[0]) |
| _srcdir = os.path.join(_scriptdir, '..', '..') |
| _distname = None |
| _distdir = None |
| _readme = None |
| |
| |
| _stdout = sys.stdout |
| _stderr = sys.stderr |
| |
| _logname = os.path.abspath(os.path.join(_scriptdir, 'make_dist.log')) |
| _logfile = open(_logname, 'w') |
| sys.stdout = _logfile |
| sys.stderr = _logfile |
| |
| def _exit(code=0): |
| if code: |
| _stderr.write('make_dist: Exit %d\n' % (code,)) |
| sys.exit(code) |
| |
| |
| # Action classes |
| |
| class MissingMethodImpl: |
| pass |
| |
| class Action: |
| def run(self, dir, cfg): |
| raise MissingMethodImpl() |
| |
| def _expand(self, cfg, value): |
| cfg.set('__expand__', '__expand__', value) |
| return cfg.get('__expand__', '__expand__') |
| |
| def _safe_expand(self, cfg, value): |
| try: |
| return self._expand(cfg, value) |
| except: |
| return None |
| |
| def _copy_file(self, source, target): |
| print('copy: %s' % source) |
| print(' to: %s' % target) |
| shutil.copyfile(source, target) |
| |
| class File(Action): |
| def __init__(self, path, name=None): |
| self.path = path |
| self.name = name |
| |
| def run(self, dir, cfg): |
| path = self._expand(cfg, self.path) |
| if self.name is None: |
| name = os.path.basename(path) |
| else: |
| name = self.name |
| self._copy_file(path, os.path.join(dir, name)) |
| |
| class OptFile(Action): |
| def __init__(self, path, name=None): |
| self.path = path |
| self.name = name |
| |
| def run(self, dir, cfg): |
| path = self._safe_expand(cfg, self.path) |
| if path is None or not os.path.isfile(path): |
| print('make_dist: File not found: %s' % self.path) |
| return |
| if self.name is None: |
| name = os.path.basename(path) |
| else: |
| name = self.name |
| self._copy_file(path, os.path.join(dir, name)) |
| |
| class FileGlob(Action): |
| def __init__(self, pattern): |
| self.pattern = pattern |
| |
| def run(self, dir, cfg): |
| pattern = self._expand(cfg, self.pattern) |
| for source in glob.glob(pattern): |
| self._copy_file(source, os.path.join(dir, os.path.basename(source))) |
| |
| class InstallDocs(Action): |
| def __init__(self, config, path): |
| self.config = config |
| self.path = path |
| |
| def run(self, dir, cfg): |
| config = self._expand(cfg, self.config) |
| pattern = os.path.join(self._expand(cfg, self.path), '*.*') |
| print('make_dist: Generating documentation') |
| old_cwd = os.getcwd() |
| try: |
| os.chdir(_srcdir) |
| _system('"%s" "%s"' % (cfg.get('tools', 'doxygen'), config)) |
| os.chdir(old_cwd) |
| FileGlob(pattern).run(dir, cfg) |
| except: |
| os.chdir(old_cwd) |
| raise |
| else: |
| os.chdir(old_cwd) |
| |
| class InstallIconv(Action): |
| def __init__(self, source, build_mode): |
| self.source = source |
| self.build_mode = build_mode |
| |
| def run(self, dir, cfg): |
| source = os.path.abspath(self._expand(cfg, self.source)) |
| build_mode = self._expand(cfg, self.build_mode) |
| print('make_dist: Installing apr-iconv modules') |
| install = ('"%s" -nologo -f Makefile.win install' |
| + ' INSTALL_DIR="%s"' |
| + ' BUILD_MODE=%s BIND_MODE=%s') \ |
| % (cfg.get('tools', 'nmake'), |
| os.path.abspath(dir), |
| build_mode, |
| 'shared') |
| old_cwd = os.getcwd() |
| try: |
| os.chdir(os.path.join(source, 'ccs')) |
| _system(install) |
| os.chdir(os.path.join(source, 'ces')) |
| _system(install) |
| except: |
| os.chdir(old_cwd) |
| raise |
| else: |
| os.chdir(old_cwd) |
| |
| class InstallJar(Action): |
| def __init__(self, jar, source): |
| self.jar = jar |
| self.source = source |
| |
| def run(self, dir, cfg): |
| source = os.path.abspath(self._expand(cfg, self.source)) |
| jarfile = os.path.abspath(os.path.join(dir, self.jar)) |
| print('make_dist: Creating jar %s' % self.jar) |
| _system('"%s" cvf "%s" -C "%s" .' |
| % (cfg.get('tools', 'jar'), jarfile, source)) |
| |
| class InstallMoFiles(Action): |
| def __init__(self, source): |
| self.source = source |
| |
| def run(self, dir, cfg): |
| pattern = os.path.join(self._expand(cfg, self.source), '*.mo') |
| for mofile in glob.glob(pattern): |
| localedir = os.path.join(dir, os.path.basename(mofile)[:-3], |
| 'LC_MESSAGES') |
| os.makedirs(localedir) |
| self._copy_file(mofile, os.path.join(localedir, 'subversion.mo')) |
| |
| # This is the distribution tree |
| _disttree = {'': OptFile('%(readme)s', 'README.txt'), |
| |
| 'bin': (File('%(blddir)s/svn/svn.exe'), |
| File('%(blddir)s/svn/svn.pdb'), |
| File('%(blddir)s/svnsync/svnsync.pdb'), |
| File('%(blddir)s/svnsync/svnsync.exe'), |
| File('%(blddir)s/svnadmin/svnadmin.exe'), |
| File('%(blddir)s/svnadmin/svnadmin.pdb'), |
| File('%(blddir)s/svnlook/svnlook.exe'), |
| File('%(blddir)s/svnlook/svnlook.pdb'), |
| File('%(blddir)s/svndumpfilter/svndumpfilter.exe'), |
| File('%(blddir)s/svndumpfilter/svndumpfilter.pdb'), |
| File('%(blddir)s/svnserve/svnserve.exe'), |
| File('%(blddir)s/svnserve/svnserve.pdb'), |
| File('%(blddir)s/svnversion/svnversion.exe'), |
| File('%(blddir)s/svnversion/svnversion.pdb'), |
| File('%(blddir)s/svnrdump/svnrdump.exe'), |
| File('%(blddir)s/svnrdump/svnrdump.pdb'), |
| File('%(blddir)s/svnmucc/svnmucc.exe'), |
| File('%(blddir)s/svnmucc/svnmucc.pdb'), |
| File('%(blddir)s/../contrib/client-side/svn-push/svn-push.exe'), |
| File('%(blddir)s/../contrib/client-side/svn-push/svn-push.pdb'), |
| File('%(blddir)s/../tools/server-side/svnauthz.exe'), |
| File('%(blddir)s/../tools/server-side/svnauthz.pdb'), |
| File('%(blddir)s/../tools/server-side/svnauthz-validate.exe'), |
| File('%(blddir)s/../tools/server-side/svnauthz-validate.pdb'), |
| File('%(blddir)s/../tools/server-side/svn-populate-node-origins-index.exe'), |
| File('%(blddir)s/../tools/server-side/svn-populate-node-origins-index.pdb'), |
| File('%(blddir)s/../tools/dev/svnraisetreeconflict/svnraisetreeconflict.exe'), |
| File('%(blddir)s/../tools/dev/svnraisetreeconflict/svnraisetreeconflict.pdb'), |
| File('%(blddir)s/mod_dav_svn/mod_dav_svn.so'), |
| File('%(blddir)s/mod_dav_svn/mod_dav_svn.pdb'), |
| File('%(blddir)s/mod_authz_svn/mod_authz_svn.so'), |
| File('%(blddir)s/mod_authz_svn/mod_authz_svn.pdb'), |
| FileGlob('%(blddir)s/libsvn_*/libsvn_*.dll'), |
| FileGlob('%(blddir)s/libsvn_*/libsvn_*.pdb'), |
| File('%(@apr)s/%(aprrel)s/libapr-1.dll'), |
| File('%(@apr)s/%(aprrel)s/libapr-1.pdb'), |
| File('%(@apr-iconv)s/%(aprrel)s/libapriconv-1.dll'), |
| File('%(@apr-iconv)s/%(aprrel)s/libapriconv-1.pdb'), |
| File('%(@apr-util)s/%(aprrel)s/libaprutil-1.dll'), |
| File('%(@apr-util)s/%(aprrel)s/libaprutil-1.pdb'), |
| File('%(@berkeley-db)s/bin/libdb%(bdbver)s.dll'), |
| File('%(@sasl)s/lib/libsasl.dll'), |
| File('%(@sasl)s/lib/libsasl.pdb'), |
| File('%(@sasl)s/utils/pluginviewer.exe'), |
| File('%(@sasl)s/utils/pluginviewer.pdb'), |
| File('%(@sasl)s/utils/sasldblistusers2.exe'), |
| File('%(@sasl)s/utils/sasldblistusers2.pdb'), |
| File('%(@sasl)s/utils/saslpasswd2.exe'), |
| File('%(@sasl)s/utils/saslpasswd2.pdb'), |
| OptFile('%(@berkeley-db)s/bin/libdb%(bdbver)s.pdb'), |
| OptFile('%(@sqlite)s/bin/sqlite3.dll'), |
| OptFile('%(@openssl)s/out32dll/libeay32.dll'), |
| OptFile('%(@openssl)s/out32dll/libeay32.pdb'), |
| OptFile('%(@openssl)s/out32dll/ssleay32.dll'), |
| OptFile('%(@openssl)s/out32dll/ssleay32.pdb'), |
| OptFile('%(@openssl)s/out32dll/openssl.exe'), |
| OptFile('%(@libintl)s/bin/intl3_svn.dll'), |
| OptFile('%(@libintl)s/bin/intl3_svn.pdb'), |
| FileGlob('%(@sasl)s/plugins/sasl*.dll'), |
| FileGlob('%(@sasl)s/plugins/sasl*.pdb'), |
| ), |
| |
| 'doc': InstallDocs('%(srcdir)s/doc/doxygen.conf', |
| '%(srcdir)s/doc/doxygen/html'), |
| |
| 'iconv': InstallIconv('%(@apr-iconv)s', '%(aprrel)s'), |
| |
| 'include': FileGlob('%(svndir)s/include/*.h'), |
| 'include/apr': FileGlob('%(@apr)s/include/*.h'), |
| 'include/apr-iconv': FileGlob('%(@apr-iconv)s/include/*.h'), |
| 'include/apr-util': FileGlob('%(@apr-util)s/include/*.h'), |
| |
| 'lib': (FileGlob('%(blddir)s/libsvn_*/*.lib'), |
| FileGlob('%(blddir)s/libsvn_*/*.pdb')), |
| 'lib/apr': File('%(@apr)s/%(aprrel)s/libapr-1.lib'), |
| 'lib/apr-iconv': File('%(@apr-iconv)s/%(aprrel)s/libapriconv-1.lib'), |
| 'lib/apr-util': (File('%(@apr-util)s/%(aprrel)s/libaprutil-1.lib'), |
| File('%(@apr-util)s/%(aprxml)s/xml.lib'), |
| File('%(@apr-util)s/%(aprxml)s/xml.pdb'), |
| ), |
| |
| 'lib/serf': (File('%(@serf)s/Release/serf.lib'), |
| ), |
| |
| 'lib/sasl': (File('%(@sasl)s/lib/libsasl.lib'), |
| File('%(@sasl)s/lib/libsasl.pdb'), |
| ), |
| |
| 'licenses': None, |
| 'licenses/bdb': File('%(@berkeley-db)s/LICENSE'), |
| 'licenses/serf': File('%(@serf)s/LICENSE'), |
| 'licenses/zlib': File('%(@zlib)s/README'), |
| 'licenses/apr-util': (File('%(@apr-util)s/LICENSE'), |
| File('%(@apr-util)s/NOTICE'), |
| ), |
| 'licenses/apr-iconv': (File('%(@apr-iconv)s/LICENSE'), |
| File('%(@apr-iconv)s/NOTICE'), |
| ), |
| 'licenses/apr': (File('%(@apr)s/LICENSE'), |
| File('%(@apr)s/NOTICE'), |
| ), |
| 'licenses/openssl': File('%(@openssl)s/LICENSE'), |
| 'licenses/svn' : File('%(srcdir)s/COPYING'), |
| 'licenses/cyrus-sasl' : File('%(@sasl)s/COPYING'), |
| |
| 'perl': None, |
| 'perl/site': None, |
| 'perl/site/lib': None, |
| 'perl/site/lib/SVN': FileGlob('%(bindsrc)s/swig/perl/native/*.pm'), |
| 'perl/site/lib/auto': None, |
| 'perl/site/lib/auto/SVN': None, |
| # Perl module DLLs defined below |
| |
| 'python': None, |
| 'python/libsvn': (FileGlob('%(binddir)s/swig/python/libsvn_swig_py/*.dll'), |
| FileGlob('%(binddir)s/swig/python/libsvn_swig_py/*.pdb'), |
| FileGlob('%(bindsrc)s/swig/python/*.py'), |
| FileGlob('%(binddir)s/swig/python/*.dll'), |
| FileGlob('%(binddir)s/swig/python/*.pdb'), |
| ), |
| 'python/svn': FileGlob('%(bindsrc)s/swig/python/svn/*.py'), |
| |
| 'javahl': (FileGlob('%(binddir)s/javahl/native/libsvn*.dll'), |
| FileGlob('%(binddir)s/javahl/native/libsvn*.pdb'), |
| InstallJar('svnjavahl.jar', |
| '%(bindsrc)s/javahl/classes'), |
| ), |
| |
| 'ruby': None, |
| 'ruby/lib': None, |
| 'ruby/lib/svn': FileGlob('%(bindsrc)s/swig/ruby/svn/*.rb'), |
| 'ruby/ext': None, |
| 'ruby/ext/svn': None, |
| 'ruby/ext/svn/ext': |
| (FileGlob('%(binddir)s/swig/ruby/*.dll'), |
| FileGlob('%(binddir)s/swig/ruby/*.pdb'), |
| FileGlob('%(binddir)s/swig/ruby/libsvn_swig_ruby/*.dll'), |
| FileGlob('%(binddir)s/swig/ruby/libsvn_swig_ruby/*.pdb'), |
| FileGlob('%(blddir)s/libsvn_*/*.dll'), |
| File('%(@berkeley-db)s/bin/libdb%(bdbver)s.dll'), |
| OptFile('%(@sqlite)s/bin/sqlite3.dll'), |
| OptFile('%(@libintl)s/bin/intl3_svn.dll'), |
| File('%(@apr)s/%(aprrel)s/libapr-1.dll'), |
| File('%(@apr-iconv)s/%(aprrel)s/libapriconv-1.dll'), |
| File('%(@apr-util)s/%(aprrel)s/libaprutil-1.dll')), |
| |
| 'share': None, |
| 'share/locale': InstallMoFiles('%(srcdir)s/%(svnrel)s/mo'), |
| } |
| |
| # Define Perl module DLLs |
| for module in ('Client', 'Core', 'Delta', 'Fs', 'Ra', 'Repos', 'Wc'): |
| _disttree['perl/site/lib/auto/SVN/_' + module] = ( |
| File('%(binddir)s/swig/perl/native/_' + module + '.dll'), |
| File('%(binddir)s/swig/perl/native/_' + module + '.pdb')) |
| |
| def _system(command): |
| def reopen_log(): |
| global _logfile |
| _logfile = open(_logname, 'a') |
| sys.stdout = _logfile |
| sys.stderr = _logfile |
| try: |
| _logfile.close() |
| sys.stdout = _stdout |
| sys.stderr = _stderr |
| os.system('"%s >>%s 2>&1"' % (command, _logname)) |
| except: |
| reopen_log() |
| raise |
| else: |
| reopen_log() |
| |
| |
| def _read_config(): |
| # Read make_dist.conf first. Fill in the default package locations. |
| path_defaults = {'@berkeley-db': |
| os.path.abspath(os.path.join(_srcdir, 'db4-win32')), |
| '@apr': |
| os.path.abspath(os.path.join(_srcdir, 'apr')), |
| '@apr-iconv': |
| os.path.abspath(os.path.join(_srcdir, 'apr-iconv')), |
| '@apr-util': |
| os.path.abspath(os.path.join(_srcdir, 'apr-util')), |
| } |
| |
| cfg = configparser.ConfigParser(path_defaults) |
| try: |
| cfg.readfp(open(os.path.join(_scriptdir, 'make_dist.conf'), 'r')) |
| except: |
| _stderr.write('Unable to open and read make_dist.conf\n') |
| _exit(1) |
| |
| # Read the options config generated by gen-make.py |
| optcfg = configparser.ConfigParser() |
| optcfg.readfp(open(os.path.join(_srcdir, 'gen-make.opts'), 'r')) |
| |
| # Move the runtime options into the DEFAULT section |
| for opt in optcfg.options('options'): |
| if not opt[:7] == '--with-': |
| continue |
| optdir = os.path.abspath(os.path.join(_srcdir, optcfg.get('options', opt))) |
| if not os.path.isdir(optdir): |
| print('make_dist: %s = %s' % (opt, optdir)) |
| print('make_dist: Target is not a directory') |
| _exit(1) |
| cfg.set('DEFAULT', '@' + opt[7:], optdir) |
| |
| # Also add the global parameters to the defaults |
| cfg.set('DEFAULT', 'srcdir', os.path.abspath(_srcdir)) |
| cfg.set('DEFAULT', 'blddir', os.path.join(_srcdir, |
| '%(svnrel)s', 'subversion')) |
| cfg.set('DEFAULT', 'svndir', os.path.join(_srcdir, 'subversion')) |
| cfg.set('DEFAULT', 'binddir', '%(blddir)s/bindings') |
| cfg.set('DEFAULT', 'bindsrc', '%(svndir)s/bindings') |
| |
| |
| if _distname is not None: |
| cfg.set('DEFAULT', 'distname', os.path.abspath(_distname)) |
| if _distdir is not None: |
| cfg.set('DEFAULT', 'distdir', os.path.abspath(_distdir)) |
| if _readme is not None: |
| cfg.set('DEFAULT', 'readme', os.path.abspath(_readme)) |
| |
| return cfg |
| |
| |
| def _make_zip(suffix, pathlist, extras): |
| zipname = '%s%s.zip' % (_distname, suffix) |
| zipcmd = '"%s" -9 -r "%s"' % (cfg.get('tools', 'zip'), zipname) |
| for path in pathlist: |
| zipcmd = zipcmd + ' "' + _distname + path + '"' |
| if extras: |
| zipcmd = zipcmd + ' ' + extras |
| old_cwd = os.getcwd() |
| try: |
| os.chdir(_distdir) |
| if os.path.exists(zipname): |
| os.remove(zipname) |
| print('make_dist: Creating %s' % zipname) |
| _stdout.write('make_dist: Creating %s\n' % zipname) |
| _system(zipcmd) |
| except: |
| os.chdir(old_cwd) |
| raise |
| else: |
| os.chdir(old_cwd) |
| |
| |
| def _make_dist(cfg): |
| try: |
| cfg.add_section('__expand__') |
| distdir = os.path.abspath(os.path.join(_distdir, _distname)) |
| if os.path.isdir(distdir): |
| shutil.rmtree(distdir) |
| os.makedirs(distdir) |
| |
| dirlist = sorted(_disttree.keys()) |
| |
| for reldir in dirlist: |
| dir = os.path.join(distdir, reldir) |
| if not os.path.exists(dir): |
| print('make_dist: Creating directory %s' % reldir) |
| _stdout.write('make_dist: Creating directory %s\n' % reldir) |
| os.makedirs(dir) |
| action = _disttree[reldir] |
| if action is None: |
| continue |
| if isinstance(action, tuple): |
| for subaction in action: |
| subaction.run(dir, cfg) |
| else: |
| action.run(dir, cfg) |
| |
| xpdb = '-x "*.pdb"' |
| _make_zip('', ('/README.txt', '/bin', '/httpd', |
| '/iconv', '/licenses', '/share/locale'), xpdb) |
| _make_zip('_dev', ('/README.txt', '/doc', '/include', '/lib'), xpdb) |
| _make_zip('_javahl', ('/README.txt', '/javahl'), xpdb) |
| _make_zip('_pdb', ('',), '-i "*.pdb"') |
| _make_zip('_pl', ('/README.txt', '/perl'), xpdb) |
| _make_zip('_py', ('/README.txt', '/python'), xpdb) |
| _make_zip('_rb', ('/README.txt', '/ruby', '/licenses', '/share/locale'), |
| xpdb) |
| |
| _stdout.write('make_dist: Creating ruby gem\n') |
| gem_script = os.path.join(_scriptdir, 'make_gem.rb') |
| rubycmd = '"%s" "%s" --output-dir="%s"' % (cfg.get('tools', 'ruby'), |
| gem_script, _distdir) |
| rubycmd += ' "' + distdir + '\\README.txt"' |
| rubycmd += ' "' + distdir + '\\ruby"' |
| rubycmd += ' "' + distdir + '\\licenses"' |
| rubycmd += ' "' + distdir + '\\share"' |
| _system(rubycmd) |
| except: |
| traceback.print_exc(None, _stderr) |
| _exit(1) |
| |
| |
| if __name__ == '__main__': |
| opts, args = my_getopt(sys.argv[1:], '', ['readme=']) |
| if len(args) != 2 or len(opts) > 1: |
| _stderr.write('Usage: make_dist.py [--readme=<file>] <distname> <distdir>\n') |
| _exit(2) |
| |
| _distname, _distdir = args |
| |
| if len(opts) != 0: |
| _readme = opts[0][1] |
| |
| cfg = _read_config() |
| _make_dist(cfg) |