PageRenderTime 93ms CodeModel.GetById 40ms app.highlight 17ms RepoModel.GetById 34ms app.codeStats 0ms

/silverlining/commands/init.py

https://bitbucket.org/ianb/silverlining/
Python | 163 lines | 156 code | 3 blank | 4 comment | 12 complexity | 321b29f0c69c98c61cc21140fd835a85 MD5 | raw file
  1"""Set up a new silver/virtualenv environment"""
  2import os
  3import sys
  4import virtualenv
  5from silversupport.shell import run
  6
  7
  8def command_init(config):
  9    dir = config.args.dir
 10    app_name = os.path.basename(os.path.abspath(dir))
 11    vars = dict(
 12        app_name=app_name,
 13        main=config.args.main,
 14        config=config.args.config)
 15    vars['force'] = config.args.force
 16    if sys.version[:3] == '2.6':
 17        virtualenv.logger = config.logger
 18        virtualenv.create_environment(
 19            dir,
 20            # This should be true to pick up global binaries like psycopg:
 21            site_packages=True,
 22            unzip_setuptools=True,
 23            use_distribute=config.args.distribute)
 24    else:
 25        # This is the crude way we need to do this when we're not in Python 2.6
 26        config.logger.warn('Creating virtualenv environment in subprocess')
 27        virtualenv_file = virtualenv.__file__
 28        if virtualenv_file.endswith('.pyc'):
 29            virtualenv_file = virtualenv_file[:-1]
 30        if config.args.distribute:
 31            cmd = [
 32                '/usr/bin/python2.6', virtualenv_file,
 33                '--unzip-setuptools', '--distribute',
 34                dir]
 35        else:
 36            cmd = [
 37                '/usr/bin/python2.6', virtualenv_file,
 38                '--unzip-setuptools', dir]
 39        run(cmd)
 40    noforce_vars = vars.copy()
 41    noforce_vars['force'] = False
 42    init_copy('README.txt', os.path.join(dir, 'README.txt'), config.logger, noforce_vars)
 43    init_copy('app.ini', os.path.join(dir, 'app.ini'), config.logger, noforce_vars)
 44    if config.args.config:
 45        init_copy('config.ini', os.path.join(dir, 'config.ini'), config.logger, vars)
 46    if config.args.main:
 47        init_copy('main.py', os.path.join(dir, 'main.py'), config.logger, vars)
 48    src = os.path.join(dir, 'src')
 49    if not os.path.exists(src):
 50        os.mkdir(src)
 51    static = os.path.join(dir, 'static')
 52    if not os.path.exists(static):
 53        os.mkdir(static)
 54    lib_python = os.path.join(dir, 'lib', 'python')
 55    if not os.path.exists(lib_python):
 56        os.makedirs(lib_python)
 57    #XXX this is a hack around http://bitbucket.org/ianb/silverlining/issue/1/bug-on-running-silver-init-for-the-second
 58    distutils_dir = os.path.join(dir, 'lib', 'python2.6', 'distutils')
 59    if os.path.islink(distutils_dir):
 60        distutils_init = os.path.join(dir, 'lib', 'python2.6', 'distutils', '__init__.py')
 61        _distutils_init_content = open(distutils_init).read()
 62        os.unlink(distutils_dir)
 63        os.makedirs(distutils_dir)
 64        init_copystring(
 65            _distutils_init_content,
 66            distutils_init,
 67            config.logger, vars, append=True)
 68
 69    init_copy(
 70        'sitecustomize.py',
 71        os.path.join(dir, 'lib', 'python2.6', 'sitecustomize.py'),
 72        config.logger, vars)
 73    init_copystring(
 74        _distutils_cfg,
 75        os.path.join(dir, 'lib', 'python2.6', 'distutils', 'distutils.cfg'),
 76        config.logger, vars, append=True)
 77    init_copystring(
 78        _distutils_init,
 79        os.path.join(dir, 'lib', 'python2.6', 'distutils', '__init__.py'),
 80        config.logger, vars, append=True)
 81    init_copystring(
 82        _activate_this,
 83        os.path.join(dir, 'bin', 'activate_this.py'),
 84        config.logger, vars, append=True)
 85_distutils_cfg = """\
 86# This is what makes things install into lib/python instead of lib/python2.6:
 87[install]
 88home = <sys.prefix>
 89"""
 90
 91_distutils_init = """\
 92
 93# Patch by silverlining:
 94old_parse_config_files = dist.Distribution.parse_config_files
 95def parse_config_files(self, filenames=None):
 96    old_parse_config_files(self, filenames)
 97    opt_dict = self.get_option_dict('install')
 98    if 'home' in opt_dict:
 99        location, value = opt_dict['home']
100        if value.lower().strip() == 'default':
101            del opt_dict['home']
102        else:
103            opt_dict['home'] = (location, value.replace('<sys.prefix>', sys.prefix))
104dist.Distribution.parse_config_files = parse_config_files
105"""
106
107_activate_this = """\
108
109# Added by silverlining:
110# This is some extra code to make activate_this.py run sitecustomize:
111sitecustomize = os.path.abspath(os.path.join(__file__, '../../lib/python%s/sitecustomize.py' % sys.version[:3]))
112if os.path.exists(sitecustomize):
113    execfile(sitecustomize, dict(__file__=sitecustomize, __name__='sitecustomize'))
114"""
115
116
117def init_copy(source, dest, logger, vars, append=False):
118    import tempita
119    source = os.path.join(
120        os.path.dirname(os.path.dirname(__file__)),
121        'init-files',
122        source)
123    if os.path.exists(source+'.tmpl'):
124        source = source+'.tmpl'
125        template = tempita.Template.from_filename(source)
126        source_content = template.substitute(vars)
127    else:
128        fp = open(source, 'rb')
129        source_content = fp.read()
130        fp.close()
131    init_copystring(source_content, dest, logger, vars,
132                    append=append)
133
134
135def init_copystring(source_content, dest, logger, vars,
136                    append=False):
137    if os.path.exists(dest):
138        fp = open(dest, 'rb')
139        content = fp.read()
140        fp.close()
141        if append:
142            if content in source_content:
143                logger.info(
144                    'Not adding to %s (already has content)' % dest)
145                return
146        else:
147            if content == source_content:
148                logger.info(
149                    'Not overwriting %s (same content)' % dest)
150                return
151            elif vars['force']:
152                logger.notify(
153                    'Overwriting %s' % dest)
154            else:
155                logger.notify(
156                    'Not overwriting %s (content differs)' % dest)
157                return
158    if append:
159        fp = open(dest, 'ab')
160    else:
161        fp = open(dest, 'wb')
162    fp.write(source_content)
163    fp.close()