/silverlining/commands/init.py
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()