Mercurial > parpg-core
diff setup.py @ 0:1fd2201f5c36
Initial commit of parpg-core.
author | M. George Hansen <technopolitica@gmail.com> |
---|---|
date | Sat, 14 May 2011 01:12:35 -0700 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/setup.py Sat May 14 01:12:35 2011 -0700 @@ -0,0 +1,292 @@ +#!/usr/bin/env python2 +""" +Cross-system setup script responsible for creating source and binary +packages for Linux, Windows, and Mac +""" +import sys +import os +import string +from distutils.core import setup, Command, Distribution as _Distribution +from distutils.command import (install as distutils_install, + build as distutils_build) +from distutils.util import subst_vars, convert_path + +distutils_install.SCHEME_KEYS += ('config',) + +# Update existing installation schemes with the new config key. +distutils_install.INSTALL_SCHEMES['unix_prefix'].update( + { + 'data' : '$base/share/$dist_name', + 'config': '$base/etc/$dist_name' + } +) +distutils_install.INSTALL_SCHEMES['unix_local'].update( + { + 'data' : '$base/local/share/$dist_name', + 'config': '$base/local/etc/$dist_name' + } +) +distutils_install.INSTALL_SCHEMES['deb_system'].update( + { + 'data' : '$base/share/$dist_name', + 'config': '$base/etc/$dist_name' + } +) +distutils_install.INSTALL_SCHEMES['unix_home'].update( + { + 'data' : '$base/share/$dist_name', + 'config': '$base/etc/$dist_name' + } +) +distutils_install.INSTALL_SCHEMES['unix_user'].update( + { + 'data' : '$userbase/share/$dist_name', + 'config': '$userbase/etc/$dist_name' + } +) +distutils_install.WINDOWS_SCHEME.update( + { + 'config': '$base' + } +) +distutils_install.INSTALL_SCHEMES['nt_user'].update( + { + 'config': '$userbase', + } +) +distutils_install.INSTALL_SCHEMES['mac'].update( + { + 'config': '$base', + } +) +distutils_install.INSTALL_SCHEMES['mac_user'].update( + { + 'config': '$userbase', + } +) +distutils_install.INSTALL_SCHEMES['os2'].update( + { + 'config': '$base', + } +) +distutils_install.INSTALL_SCHEMES['os2_home'].update( + { + 'config': '$userbase', + } +) + + +class build_templates(Command): + description = '"build" template files (copy to build directory, ' \ + 'substituting build variables)' + user_options = [ + ('build-dir=', 'd', 'directory to "build" (copy) to'), + ('force', 'f', 'forcibly build everything (ignore file timestamps)'), + ] + boolean_options = ['force'] + + def initialize_options(self): + self.build_base = None + self.build_dir = None + self.force = None + self.config_vars = None + self.templates = None + + def finalize_options(self): + self.set_undefined_options( + 'build', + ('build_base', 'build_base'), + ('force', 'force'), + ) + self.build_dir = os.path.join(self.build_base, 'templates') + self.set_undefined_options('install', ('config_vars', 'config_vars')) + self.templates = self.distribution.templates + + def run(self): + if self.has_templates(): + self.build_templates() + + def build_templates(self): + build_dir = self.build_dir + for template_path, outfile_rel_path in self.templates.items(): + outfile_path = os.path.join(build_dir, outfile_rel_path) + self.copy_file(template_path, outfile_path, preserve_mode=False) + self.substitute_template(outfile_path) + + def substitute_template(self, file_path): + with file(file_path, 'r') as template_file: + template_content = template_file.read() + template = string.Template(template_content) + config_vars = self.config_vars + file_content = template.substitute(config_vars) + with file(file_path, 'w') as config_file: + config_file.write(file_content) + + def has_templates(self): + return self.distribution.has_templates() + + +class install_config(Command): + description = 'install configuration files' + user_options = [ + ('install-dir=', 'd', 'directory to install configuration files to'), + ('force', 'f', 'force installation (overwrite existing files)'), + ('skip-build', None, 'skip the build steps'), + ] + boolean_options = ['force', 'skip-build'] + + def initialize_options(self): + self.install_dir = None + self.force = 0 + self.skip_build = None + self.config_files = None + self.config_templates = None + self.config_vars = None + + def finalize_options(self): + self.set_undefined_options( + 'install', + ('install_config', 'install_dir'), + ('force', 'force'), + ('skip_build', 'skip_build'), + ('config_vars', 'config_vars'), + ) + self.config_files = self.distribution.config_files + self.config_templates = self.distribution.config_templates + + def run(self): + install_dir = self.install_dir + outfiles = [] + for file_path in self.config_files: + output_file_path = os.path.join(install_dir, file_path) + output_dir_path = os.path.dirname(output_file_path) + self.mkpath(output_dir_path) + outfile = self.copy_file(file_path, output_dir_path, + preserve_mode=0) + outfiles.append(outfile) + self.outfiles = outfiles + + def get_inputs(self): + return self.distribution.config_files or [] + + def get_outputs(self): + return self.outfiles or [] + + +class install(distutils_install.install): + user_options = distutils_install.install.user_options + [ + ('install-config=', None, + 'installation directory for system-wide configuration files') + ] + + def has_config(self): + return self.distribution.has_config() + + def has_templates(self): + return self.distribution.has_templates() + + def initialize_options(self): + self.install_config = None + distutils_install.install.initialize_options(self) + + def finalize_options(self): + distutils_install.install.finalize_options(self) + # FIXME M. George Hansen 2011-05-11: Probably shouldn't be using a + # private method here... + self._expand_attrs(['install_config']) + self.convert_paths('config') + self.config_vars['config'] = self.install_config + if self.root is not None: + self.change_roots('config') + install_scheme = self.install_scheme + for key, value in install_scheme.items(): + if os.name in ['posix', 'nt']: + value = os.path.expanduser(value) + value = subst_vars(value, self.config_vars) + value = convert_path(value) + self.config_vars[key] = value + + def select_scheme(self, name): + # Store the selected scheme for later processing. + distutils_install.install.select_scheme(self, name) + self.install_scheme = distutils_install.INSTALL_SCHEMES[name] + + def get_program_files_path(self): + assert sys.platform == 'win32' + try: + program_files_path = os.environ['ProgramFiles'] + except KeyError: + # ProgramFiles environmental variable isn't set, so we'll have to + # find it ourselves. Bit of a hack, but better than nothing. + program_files_path = '' + try: + import win32api + except ImportError: + program_files_path = '' + else: + drive_names = \ + [drive_name for drive_name in + win32api.GetLogicalDriveStrings().split('\000') if + drive_name] + for drive_name in drive_names: + search_path = os.path.join(drive_name, 'Program Files') + if os.path.isdir(search_path): + program_files_path = search_path + if not program_files_path: + error_message = 'unable to determine path to Program Files' + raise error_message + + return program_files_path + + sub_commands = distutils_install.install.sub_commands + [ + ('install_config', has_config), + ] + + +class build(distutils_build.build): + def has_templates(self): + return self.distribution.has_templates() + + sub_commands = [('build_templates', has_templates)] + \ + distutils_build.build.sub_commands + + +class Distribution(_Distribution): + def __init__(self, attrs=None): + self.templates = {} + self.config_files = [] + _Distribution.__init__(self, attrs) + + def has_config(self): + return self.config_files and len(self.config_files) > 0 + + def has_templates(self): + return self.templates and len(self.templates) > 0 + + +setup( + name='parpg', + scripts=['parpg'], + templates={'system.cfg': 'system.cfg.in', 'parpg': 'parpg.in'}, + config_files=['system.cfg'], + packages=['parpg'], + modules=['src/main.py'], + package_dir={'parpg': 'src/parpg'}, + version='0.2.0', + url='http://www.parpg.net', + description='', + long_description='', + cmdclass={'install': install, 'install_config': install_config, + 'build': build, 'build_templates': build_templates}, + distclass=Distribution, + classifiers=[ + 'Programming Language :: Python', + 'License :: OSI Approved :: GNU General Public License (GPL)', + 'Intended Audience :: End Users/Desktop', + 'Intended Audience :: Developers', + 'Development Status :: 2 - Pre-Alpha', + 'Operating System :: OS Independent', + 'Natural Language :: English', + 'Topic :: Games/Entertainment :: Role-Playing', + ], +)