1 # Copyright (C) 2013 Vinay Sajip. New BSD License.
2 # Copyright (C) 2014 Kaliko Jack
4 from __future__ import print_function
8 if sys.version_info < REQ_VER:
9 print('Need at least python {0}.{1} to run this script'.format(*REQ_VER), file=sys.stderr)
16 from subprocess import Popen, PIPE
17 from threading import Thread
18 from urllib.parse import urlparse
19 from urllib.request import urlretrieve
20 from shutil import rmtree
22 class ExtendedEnvBuilder(venv.EnvBuilder):
24 This builder installs setuptools and pip so that you can pip or
25 easy_install other packages into the created environment.
28 def __init__(self, *args, **kwargs):
29 self.verbose = kwargs.pop('verbose', False)
30 super().__init__(*args, **kwargs)
32 def post_setup(self, context):
34 Set up any packages which need to be pre-installed into the
35 environment being created.
37 :param context: The information for the environment creation request
40 os.environ['VIRTUAL_ENV'] = context.env_dir
41 self.install_setuptools(context)
42 self.install_pip(context)
43 setup = os.path.abspath(os.path.join(context.env_dir, '../setup.py'))
44 self.install_script(context, 'sima', setup=setup)
46 def reader(self, stream, context):
48 Read lines from a subprocess' output stream and write progress
49 information to sys.stderr.
58 sys.stderr.write(s.decode('utf-8'))
62 def install_script(self, context, name, url=None, setup=None):
64 binpath = context.bin_path
65 _, _, path, _, _, _ = urlparse(url)
66 fn = os.path.split(path)[-1]
67 distpath = os.path.join(binpath, fn)
68 # Download script into the env's binaries folder
69 urlretrieve(url, distpath)
71 args = [context.env_exe, fn]
73 args = [context.env_exe, setup, 'install']
74 binpath = os.path.dirname(setup)
79 sys.stderr.write('Installing %s ...%s' % (name, term))
82 p = Popen(args, stdout=PIPE, stderr=PIPE, cwd=binpath)
83 t1 = Thread(target=self.reader, args=(p.stdout, 'stdout'))
85 t2 = Thread(target=self.reader, args=(p.stderr, 'stderr'))
90 sys.stderr.write('done.\n')
92 # Clean up - no longer needed
95 def install_setuptools(self, context):
97 Install setuptools in the environment.
99 :param context: The information for the environment creation request
102 url = 'https://bitbucket.org/pypa/setuptools/downloads/ez_setup.py'
103 self.install_script(context, 'setuptools', url)
104 # clear up the setuptools archive which gets downloaded
105 pred = lambda o: o.startswith('setuptools-') and o.endswith('.tar.gz')
106 files = filter(pred, os.listdir(context.bin_path))
108 f = os.path.join(context.bin_path, f)
111 def install_pip(self, context):
113 Install pip in the environment.
115 :param context: The information for the environment creation request
118 url = 'https://raw.github.com/pypa/pip/master/contrib/get-pip.py'
119 self.install_script(context, 'pip', url)
120 # pip installs to "local/bin" on Linux, but it needs to be accessible
121 # from "bin" since the "activate" script prepends "bin" to $PATH
122 pip_path = os.path.join(context.env_dir, 'local', 'bin', 'pip')
123 if sys.platform != 'win32' and os.path.exists(pip_path):
124 self.symlink_or_copy(pip_path, os.path.join(context.bin_path, 'pip'))
128 root = os.path.dirname(os.path.abspath(__file__))
129 vdir = os.path.join(root, 'venv')
130 builder = ExtendedEnvBuilder(clear=True, verbose=False)
133 for residu in ['MPD_sima.egg-info', 'dist', 'build']:
134 if os.path.exists(os.path.join(root, residu)):
135 rmtree(os.path.join(root, residu))
137 with open(os.path.join(root, 'vmpd-sima'),'w') as fd:
138 fd.write('#!/bin/sh\n')
139 fd.write('. "{}/venv/bin/activate"\n'.format(root))
140 fd.write('"{}/venv/bin/mpd-sima" "$@"'.format(root))
141 os.chmod(os.path.join(root, 'vmpd-sima'), 0o744)
143 if __name__ == '__main__':
148 except ImportError as e:
149 print('Error: %s' % e)