<s> import os <EOL> import sys <EOL> import shutil <EOL> import glob <EOL> from os . path import join , realpath , dirname , normpath , normcase <EOL> from operator import methodcaller <EOL> try : <EOL> from urlparse import urlparse <EOL> except ImportError : <EOL> from urllib . parse import urlparse <EOL> import click <EOL> from pkg_resources import Requirement <EOL> try : <EOL> WindowsError <EOL> except NameError : <EOL> IS_WIN = False <EOL> BIN_DIR = '<STR_LIT>' <EOL> else : <EOL> IS_WIN = True <EOL> BIN_DIR = '<STR_LIT>' <EOL> FIND_SCRIPTS_SCRIPT = r'''<STR_LIT>''' <EOL> CONTEXT_SETTINGS = dict ( <EOL> help_option_names = [ '<STR_LIT>' , '<STR_LIT>' ] , <EOL> ) <EOL> def normalize_package ( value ) : <EOL> requirement = Requirement . parse ( value ) <EOL> return requirement . project_name . lower ( ) <EOL> def normalize ( path ) : <EOL> return normcase ( normpath ( realpath ( path ) ) ) <EOL> def real_readlink ( filename ) : <EOL> try : <EOL> target = os . readlink ( filename ) <EOL> except ( OSError , IOError , AttributeError ) : <EOL> return None <EOL> return normpath ( realpath ( join ( dirname ( filename ) , target ) ) ) <EOL> def statusoutput ( argv , ** kw ) : <EOL> from subprocess import Popen , PIPE <EOL> p = Popen ( <EOL> argv , stdout = PIPE , stderr = PIPE , ** kw ) <EOL> output = p . communicate ( ) [ <NUM_LIT:0> ] . strip ( ) <EOL> if not isinstance ( output , str ) : <EOL> output = output . decode ( '<STR_LIT:utf-8>' , '<STR_LIT:replace>' ) <EOL> return p . returncode , output <EOL> def publish_script ( src , dst ) : <EOL> if IS_WIN : <EOL> shutil . copy ( src , dst ) <EOL> click . echo ( '<STR_LIT>' + dst ) <EOL> return True <EOL> else : <EOL> old_target = real_readlink ( dst ) <EOL> if old_target == src : <EOL> return True <EOL> try : <EOL> os . remove ( dst ) <EOL> except OSError : <EOL> pass <EOL> try : <EOL> os . symlink ( src , dst ) <EOL> except OSError : <EOL> pass <EOL> else : <EOL> click . echo ( '<STR_LIT>' + dst ) <EOL> return True <EOL> def find_scripts ( virtualenv , package ) : <EOL> prefix = normalize ( join ( virtualenv , BIN_DIR , '<STR_LIT>' ) ) <EOL> files = statusoutput ( [ <EOL> join ( prefix , '<STR_LIT>' ) , '<STR_LIT:-c>' , FIND_SCRIPTS_SCRIPT , <EOL> package , prefix <EOL> ] ) [ <NUM_LIT:1> ] . splitlines ( ) <EOL> files = map ( normalize , files ) <EOL> files = filter ( <EOL> methodcaller ( '<STR_LIT>' , prefix ) , <EOL> files , <EOL> ) <EOL> def valid ( filename ) : <EOL> return os . path . isfile ( filename ) and IS_WIN or os . access ( filename , os . X_OK ) <EOL> result = list ( filter ( valid , files ) ) <EOL> if IS_WIN : <EOL> for filename in files : <EOL> globed = glob . glob ( filename + '<STR_LIT:*>' ) <EOL> result . extend ( filter ( valid , globed ) ) <EOL> return result <EOL> class UninstallInfo ( object ) : <EOL> def __init__ ( self , package , paths = None , installed = True ) : <EOL> self . package = package <EOL> self . paths = paths or [ ] <EOL> self . installed = installed <EOL> def perform ( self ) : <EOL> for path in self . paths : <EOL> try : <EOL> os . remove ( path ) <EOL> except OSError : <EOL> shutil . rmtree ( path ) <EOL> class Repo ( object ) : <EOL> def __init__ ( self , home , bin_dir ) : <EOL> self . home = home <EOL> self . bin_dir = bin_dir <EOL> def resolve_package ( self , spec , python = None ) : <EOL> url = urlparse ( spec ) <EOL> if url . netloc == '<STR_LIT:file>' : <EOL> location = url . path <EOL> elif url . netloc != '<STR_LIT>' : <EOL> if not url . fragment . startswith ( '<STR_LIT>' ) : <EOL> raise click . UsageError ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> return url . fragment [ <NUM_LIT:4> : ] , [ spec ] <EOL> elif os . path . isdir ( spec ) : <EOL> location = spec <EOL> else : <EOL> return spec , [ spec ] <EOL> error , name = statusoutput ( <EOL> [ python or sys . executable , '<STR_LIT>' , '<STR_LIT>' ] , <EOL> cwd = location ) <EOL> if error : <EOL> raise click . UsageError ( '<STR_LIT>' <EOL> '<STR_LIT>' % spec ) <EOL> return name , [ location ] <EOL> def get_package_path ( self , package ) : <EOL> return join ( self . home , normalize_package ( package ) ) <EOL> def find_installed_executables ( self , path ) : <EOL> prefix = join ( realpath ( normpath ( path ) ) , '<STR_LIT>' ) <EOL> try : <EOL> for filename in os . listdir ( self . bin_dir ) : <EOL> exe = os . path . join ( self . bin_dir , filename ) <EOL> target = real_readlink ( exe ) <EOL> if target is None : <EOL> continue <EOL> if target . startswith ( prefix ) : <EOL> yield exe <EOL> except OSError : <EOL> pass <EOL> def link_scripts ( self , scripts ) : <EOL> rv = [ ] <EOL> for script in scripts : <EOL> script_dst = os . path . join ( <EOL> self . bin_dir , os . path . basename ( script ) ) <EOL> if publish_script ( script , script_dst ) : <EOL> rv . append ( ( script , script_dst ) ) <EOL> return rv <EOL> def install ( self , package , python = None , editable = False , system_site_packages = False ) : <EOL> package , install_args = self . resolve_package ( package , python ) <EOL> venv_path = self . get_package_path ( package ) <EOL> if os . path . isdir ( venv_path ) : <EOL> click . echo ( '<STR_LIT>' % package ) <EOL> return <EOL> if not os . path . exists ( self . bin_dir ) : <EOL> os . makedirs ( self . bin_dir ) <EOL> from subprocess import Popen <EOL> def _cleanup ( ) : <EOL> try : <EOL> shutil . rmtree ( venv_path ) <EOL> except ( OSError , IOError ) : <EOL> pass <EOL> return False <EOL> args = [ '<STR_LIT>' , '<STR_LIT>' , python or sys . executable , venv_path ] <EOL> if system_site_packages : <EOL> args . append ( '<STR_LIT>' ) <EOL> try : <EOL> if Popen ( args ) . wait ( ) != <NUM_LIT:0> : <EOL> click . echo ( '<STR_LIT>' ) <EOL> return _cleanup ( ) <EOL> args = [ os . path . join ( venv_path , BIN_DIR , '<STR_LIT>' ) , '<STR_LIT>' ] <EOL> if editable : <EOL> args . append ( '<STR_LIT>' ) <EOL> if Popen ( args + install_args ) . wait ( ) != <NUM_LIT:0> : <EOL> click . echo ( '<STR_LIT>' ) <EOL> return _cleanup ( ) <EOL> except Exception : <EOL> _cleanup ( ) <EOL> raise <EOL> scripts = find_scripts ( venv_path , package ) <EOL> linked_scripts = self . link_scripts ( scripts ) <EOL> if not linked_scripts : <EOL> click . echo ( '<STR_LIT>' ) <EOL> return _cleanup ( ) <EOL> return True <EOL> def uninstall ( self , package ) : <EOL> path = self . get_package_path ( package ) <EOL> if not os . path . isdir ( path ) : <EOL> return UninstallInfo ( package , installed = False ) <EOL> paths = [ path ] <EOL> paths . extend ( self . find_installed_executables ( path ) ) <EOL> return UninstallInfo ( package , paths ) <EOL> def upgrade ( self , package , editable = False ) : <EOL> package , install_args = self . resolve_package ( package ) <EOL> venv_path = self . get_package_path ( package ) <EOL> if not os . path . isdir ( venv_path ) : <EOL> click . echo ( '<STR_LIT>' % package ) <EOL> return <EOL> from subprocess import Popen <EOL> old_scripts = set ( find_scripts ( venv_path , package ) ) <EOL> args = [ os . path . join ( venv_path , BIN_DIR , '<STR_LIT>' ) , '<STR_LIT>' , <EOL> '<STR_LIT>' ] <EOL> if editable : <EOL> args . append ( '<STR_LIT>' ) <EOL> if Popen ( args + install_args ) . wait ( ) != <NUM_LIT:0> : <EOL> click . echo ( '<STR_LIT>' ) <EOL> return <EOL> scripts = find_scripts ( venv_path , package ) <EOL> linked_scripts = self . link_scripts ( scripts ) <EOL> to_delete = old_scripts - set ( x [ <NUM_LIT:0> ] for x in linked_scripts ) <EOL> for script_src , script_link in linked_scripts : <EOL> if script_src in to_delete : <EOL> try : <EOL> click . echo ( '<STR_LIT>' % script_src ) <EOL> os . remove ( script_link ) <EOL> except ( IOError , OSError ) : <EOL> pass <EOL> def list_everything ( self ) : <EOL> venvs = { } <EOL> python = '<STR_LIT>' if IS_WIN else '<STR_LIT>' <EOL> for venv in os . listdir ( self . home ) : <EOL> venv_path = os . path . join ( self . home , venv ) <EOL> if os . path . isdir ( venv_path ) and os . path . isfile ( venv_path + python ) : <EOL> venvs [ venv ] = list ( self . find_installed_executables ( venv_path ) ) <EOL> return sorted ( venvs . items ( ) ) <EOL> @ click . group ( context_settings = CONTEXT_SETTINGS ) <EOL> @ click . option ( <EOL> '<STR_LIT>' , type = click . Path ( ) , envvar = '<STR_LIT>' , <EOL> default = os . path . expanduser ( '<STR_LIT>' ) , <EOL> help = '<STR_LIT>' ) <EOL> @ click . option ( <EOL> '<STR_LIT>' , type = click . Path ( ) , <EOL> envvar = '<STR_LIT>' , <EOL> default = os . path . expanduser ( '<STR_LIT>' ) , <EOL> help = '<STR_LIT>' ) <EOL> @ click . version_option ( <EOL> message = '<STR_LIT>' + str ( sys . executable ) ) <EOL> @ click . pass_context <EOL> def cli ( ctx , home , bin_dir ) : <EOL> """<STR_LIT>""" <EOL> ctx . obj = Repo ( home , bin_dir ) <EOL> @ cli . command ( ) <EOL> @ click . argument ( '<STR_LIT>' ) <EOL> @ click . option ( '<STR_LIT>' , default = None , <EOL> help = '<STR_LIT>' ) <EOL> @ click . option ( '<STR_LIT>' , '<STR_LIT>' , is_flag = True , <EOL> help = '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> @ click . option ( '<STR_LIT>' , is_flag = True , <EOL> help = '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> @ click . pass_obj <EOL> def install ( repo , package , python , editable , system_site_packages ) : <EOL> """<STR_LIT>""" <EOL> if repo . install ( package , python , editable , system_site_packages ) : <EOL> click . echo ( '<STR_LIT>' ) <EOL> else : <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> @ cli . command ( ) <EOL> @ click . argument ( '<STR_LIT>' ) <EOL> @ click . option ( '<STR_LIT>' , '<STR_LIT>' , is_flag = True , <EOL> help = '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> @ click . pass_obj <EOL> def upgrade ( repo , package , editable ) : <EOL> """<STR_LIT>""" <EOL> if repo . upgrade ( package , editable ) : <EOL> click . echo ( '<STR_LIT>' ) <EOL> else : <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> @ cli . command ( short_help = '<STR_LIT>' ) <EOL> @ click . argument ( '<STR_LIT>' ) <EOL> @ click . option ( '<STR_LIT>' , is_flag = True , help = '<STR_LIT>' ) <EOL> @ click . pass_obj <EOL> def uninstall ( repo , package , yes ) : <EOL> """<STR_LIT>""" <EOL> uinfo = repo . uninstall ( package ) <EOL> if not uinfo . installed : <EOL> click . echo ( '<STR_LIT>' % package ) <EOL> else : <EOL> click . echo ( '<STR_LIT>' ) <EOL> for path in uinfo . paths : <EOL> click . echo ( '<STR_LIT>' % click . format_filename ( path ) ) <EOL> click . echo ( ) <EOL> if yes or click . confirm ( '<STR_LIT>' % package ) : <EOL> uinfo . perform ( ) <EOL> click . echo ( '<STR_LIT>' ) <EOL> else : <EOL> click . echo ( '<STR_LIT>' ) <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> @ cli . command ( '<STR_LIT:list>' ) <EOL> @ click . pass_obj <EOL> def list_cmd ( repo ) : <EOL> """<STR_LIT>""" <EOL> click . echo ( '<STR_LIT>' ) <EOL> for venv , scripts in repo . list_everything ( ) : <EOL> if not scripts : <EOL> continue <EOL> click . echo ( '<STR_LIT>' % venv ) <EOL> for script in scripts : <EOL> click . echo ( '<STR_LIT:U+0020>' + script ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> cli ( ) </s>
