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',
+    ],
+)