@task(help=dict(<EOL>pyrun="<STR_LIT>",<EOL>upload="<STR_LIT>",<EOL>opts="<STR_LIT>",<EOL>))<EOL>def pex(ctx, pyrun='<STR_LIT>', upload=False, opts='<STR_LIT>'):
cfg = config.load()<EOL>ctx.run("<STR_LIT>")<EOL>pkg_info = get_egg_info(cfg)<EOL>version = pkg_info.version if pkg_info else cfg.project.version<EOL>pex_files = []<EOL>for script in cfg.project.entry_points['<STR_LIT>']:<EOL><INDENT>script, entry_point = script.split('<STR_LIT:=>', <NUM_LIT:1>)<EOL>script, entry_point = script.strip(), entry_point.strip()<EOL>pex_file = cfg.rootjoin('<STR_LIT>', '<STR_LIT>'.format(script, version))<EOL>cmd = ['<STR_LIT>', '<STR_LIT>', cfg.rootjoin('<STR_LIT>'), cfg.project_root, '<STR_LIT:-c>', script, '<STR_LIT>', pex_file]<EOL>if opts:<EOL><INDENT>cmd.append(opts)<EOL><DEDENT>ctx.run('<STR_LIT:U+0020>'.join(cmd))<EOL>non_universal = set()<EOL>with closing(zipfile.ZipFile(pex_file, mode="<STR_LIT:r>")) as pex_contents:<EOL><INDENT>for pex_name in pex_contents.namelist():  <EOL><INDENT>if pex_name.endswith('<STR_LIT>') and '<STR_LIT>' not in pex_name:<EOL><INDENT>non_universal.add(pex_name.split('<STR_LIT>')[<NUM_LIT:0>].split('<STR_LIT:/>')[-<NUM_LIT:1>])<EOL><DEDENT><DEDENT><DEDENT>if non_universal:<EOL><INDENT>notify.warning("<STR_LIT>"<EOL>.format(pex_file.replace(os.getcwd(), '<STR_LIT:.>'), '<STR_LIT>'.join(sorted(non_universal))))<EOL>envs = [i.split('<STR_LIT:->')[-<NUM_LIT:3>:] for i in non_universal]<EOL>envs = {i[<NUM_LIT:0>]: i[<NUM_LIT:1>:] for i in envs}<EOL>if len(envs) > <NUM_LIT:1>:<EOL><INDENT>envs = {k: v for k, v in envs.items() if not k.startswith('<STR_LIT>')}<EOL><DEDENT>env_id = []<EOL>for k, v in sorted(envs.items()):<EOL><INDENT>env_id.append(k)<EOL>env_id.extend(v)<EOL><DEDENT>env_id = '<STR_LIT:->'.join(env_id)<EOL><DEDENT>else:<EOL><INDENT>env_id = '<STR_LIT>'<EOL><DEDENT>new_pex_file = pex_file.replace('<STR_LIT>', '<STR_LIT>'.format(env_id))<EOL>notify.info("<STR_LIT>".format(os.path.basename(new_pex_file)))<EOL>os.rename(pex_file, new_pex_file)<EOL>pex_file = new_pex_file<EOL>pex_files.append(pex_file)<EOL><DEDENT>if not pex_files:<EOL><INDENT>notify.warning("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>if pyrun:<EOL><INDENT>if any(pyrun.startswith(i) for i in ('<STR_LIT>', '<STR_LIT>', '<STR_LIT>')):<EOL><INDENT>pyrun_url = pyrun<EOL><DEDENT>else:<EOL><INDENT>pyrun_cfg = dict(ctx.rituals.pyrun)<EOL>pyrun_cfg.update(parse_qsl(pyrun.replace(os.pathsep, '<STR_LIT:&>')))<EOL>pyrun_url = (pyrun_cfg['<STR_LIT>'] + '<STR_LIT:/>' +<EOL>pyrun_cfg['<STR_LIT>']).format(**pyrun_cfg)<EOL><DEDENT>notify.info("<STR_LIT>".format(pyrun_url))<EOL>with url_as_file(pyrun_url, ext='<STR_LIT>') as pyrun_tarball:<EOL><INDENT>pyrun_tar = tarfile.TarFile.gzopen(pyrun_tarball)<EOL>for pex_file in pex_files[:]:<EOL><INDENT>pyrun_exe = pyrun_tar.extractfile('<STR_LIT>')<EOL>with open(pex_file, '<STR_LIT:rb>') as pex_handle:<EOL><INDENT>pyrun_pex_file = '<STR_LIT>'.format(<EOL>pex_file[:-<NUM_LIT:4>], pyrun_url.rsplit('<STR_LIT>')[-<NUM_LIT:1>][:-<NUM_LIT:4>])<EOL>with open(pyrun_pex_file, '<STR_LIT:wb>') as pyrun_pex:<EOL><INDENT>pyrun_pex.write(INSTALLER_BASH.replace('<STR_LIT>', '<STR_LIT>'.format(len(INSTALLER_BASH) + <NUM_LIT:1>)))<EOL>shutil.copyfileobj(pyrun_exe, pyrun_pex)<EOL>shutil.copyfileobj(pex_handle, pyrun_pex)<EOL><DEDENT>shutil.copystat(pex_file, pyrun_pex_file)<EOL>notify.info("<STR_LIT>".format(pretty_path(pyrun_pex_file)))<EOL>pex_files.append(pyrun_pex_file)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>if upload:<EOL><INDENT>base_url = ctx.rituals.release.upload.base_url.rstrip('<STR_LIT:/>')<EOL>if not base_url:<EOL><INDENT>notify.failure("<STR_LIT>")<EOL><DEDENT>for pex_file in pex_files:<EOL><INDENT>url = base_url + '<STR_LIT:/>' + ctx.rituals.release.upload.path.lstrip('<STR_LIT:/>').format(<EOL>name=cfg.project.name, version=cfg.project.version, filename=os.path.basename(pex_file))<EOL>notify.info("<STR_LIT>".format(url))<EOL>with io.open(pex_file, '<STR_LIT:rb>') as handle:<EOL><INDENT>reply = requests.put(url, data=handle.read())<EOL>if reply.status_code in range(<NUM_LIT:200>, <NUM_LIT>):<EOL><INDENT>notify.info("<STR_LIT>".format(**vars(reply)))<EOL><DEDENT>else:<EOL><INDENT>notify.warning("<STR_LIT>".format(**vars(reply)))<EOL><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT>
Package the project with PEX.