<s> from __future__ import absolute_import , print_function , unicode_literals <EOL> from . import _osx as osx <EOL> from . import _tty as tty <EOL> from . exceptions import ( <EOL> UnsupportedOSError , XcodeMissingError , BrewMissingError , <EOL> SymlinkError , AppMissingError , StowError <EOL> ) <EOL> from . _lib import lazyproperty <EOL> from . _sh import ( <EOL> Brew , Defaults , spawn , collapseuser , commonpath , curl , mkdir_p , <EOL> read_config , write_config , modify_config , isdirname , prompt <EOL> ) <EOL> from fnmatch import fnmatch <EOL> from glob import iglob <EOL> from rfc3987 import parse as urlparse <EOL> from tempfile import mkdtemp <EOL> import click <EOL> import errno <EOL> import json <EOL> import os <EOL> import platform <EOL> import re <EOL> import shutil <EOL> import subprocess <EOL> import sys <EOL> _DEFAULTS_TRUE_RE = re . compile ( r"<STR_LIT>" , re . I ) <EOL> _DEFAULTS_FALSE_RE = re . compile ( r"<STR_LIT>" , re . I ) <EOL> class Cider ( object ) : <EOL> def __init__ ( self , cask = None , debug = None , verbose = None , cider_dir = None , <EOL> support_dir = None ) : <EOL> self . cask = cask if cask is not None else False <EOL> self . debug = debug if debug is not None else False <EOL> self . verbose = verbose if verbose is not None else False <EOL> self . cider_dir = cider_dir if cider_dir is not None else self . fallback_cider_dir ( ) <EOL> self . support_dir = support_dir if support_dir is not None else self . fallback_support_dir ( ) <EOL> self . brew = Brew ( cask , debug , verbose , self . env ) <EOL> self . defaults = Defaults ( debug , self . env ) <EOL> @ lazyproperty <EOL> def symlink_dir ( self ) : <EOL> return os . path . join ( self . cider_dir , "<STR_LIT>" ) <EOL> @ lazyproperty <EOL> def bootstrap_file ( self ) : <EOL> legacy_path = os . path . join ( self . cider_dir , "<STR_LIT>" ) <EOL> if os . path . isfile ( legacy_path ) : <EOL> return legacy_path <EOL> return os . path . join ( self . cider_dir , "<STR_LIT>" ) <EOL> @ lazyproperty <EOL> def defaults_file ( self ) : <EOL> legacy_path = os . path . join ( self . cider_dir , "<STR_LIT>" ) <EOL> if os . path . isfile ( legacy_path ) : <EOL> return legacy_path <EOL> return os . path . join ( self . cider_dir , "<STR_LIT>" ) <EOL> @ lazyproperty <EOL> def env ( self ) : <EOL> env = os . environ . copy ( ) <EOL> env . update ( self . read_bootstrap ( ) . get ( "<STR_LIT>" , { } ) ) <EOL> return env <EOL> def fallback_cider_dir ( self ) : <EOL> try : <EOL> return os . path . join ( os . environ [ "<STR_LIT>" ] , "<STR_LIT>" ) <EOL> except KeyError : <EOL> return os . path . join ( os . path . expanduser ( "<STR_LIT>" ) , "<STR_LIT>" ) <EOL> def fallback_support_dir ( self ) : <EOL> try : <EOL> return os . path . join ( os . environ [ "<STR_LIT>" ] , "<STR_LIT>" ) <EOL> except KeyError : <EOL> return os . path . join ( <EOL> os . path . expanduser ( "<STR_LIT>" ) , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" <EOL> ) <EOL> @ lazyproperty <EOL> def symlink_targets_file ( self ) : <EOL> return os . path . join ( self . support_dir , "<STR_LIT>" ) <EOL> def read_bootstrap ( self ) : <EOL> return read_config ( self . bootstrap_file , { } ) <EOL> def read_defaults ( self ) : <EOL> return read_config ( self . defaults_file , { } ) <EOL> def _check_cider_dir ( self ) : <EOL> if not os . path . isdir ( self . cider_dir ) : <EOL> os . mkdir ( self . cider_dir ) <EOL> print ( tty . progress ( "<STR_LIT>" . format ( <EOL> self . cider_dir <EOL> ) ) ) <EOL> def _modify_bootstrap ( self , key , transform = None , fallback = None ) : <EOL> if transform is None : <EOL> transform = lambda x : x <EOL> if fallback is None : <EOL> fallback = [ ] <EOL> def outer_transform ( bootstrap ) : <EOL> bootstrap [ key ] = transform ( bootstrap . get ( key , fallback ) ) <EOL> if isinstance ( bootstrap [ key ] , list ) : <EOL> bootstrap [ key ] = sorted ( bootstrap [ key ] ) <EOL> return bootstrap <EOL> self . _check_cider_dir ( ) <EOL> return modify_config ( self . bootstrap_file , outer_transform ) <EOL> def _modify_defaults ( self , domain , transform ) : <EOL> def outer_transform ( defaults ) : <EOL> defaults [ domain ] = transform ( defaults . get ( domain , { } ) ) <EOL> return defaults <EOL> self . _check_cider_dir ( ) <EOL> return modify_config ( self . defaults_file , outer_transform ) <EOL> def _cached_targets ( self ) : <EOL> return read_config ( self . symlink_targets_file , [ ] ) <EOL> def _update_target_cache ( self , new_targets ) : <EOL> self . _check_cider_dir ( ) <EOL> mkdir_p ( os . path . dirname ( self . symlink_targets_file ) ) <EOL> write_config ( self . symlink_targets_file , sorted ( new_targets ) ) <EOL> def _remove_dead_targets ( self , targets ) : <EOL> for target in targets : <EOL> if os . path . islink ( target ) and os . path . samefile ( <EOL> self . cider_dir , <EOL> commonpath ( [ <EOL> self . cider_dir , <EOL> os . path . realpath ( target ) <EOL> ] ) , <EOL> ) : <EOL> os . remove ( target ) <EOL> print ( tty . progress ( "<STR_LIT>" . format ( <EOL> collapseuser ( target ) ) <EOL> ) ) <EOL> @ staticmethod <EOL> def _remove_link_target ( source , target ) : <EOL> if os . path . exists ( target ) : <EOL> if os . path . samefile ( os . path . realpath ( target ) , <EOL> os . path . realpath ( source ) ) : <EOL> os . remove ( target ) <EOL> else : <EOL> raise SymlinkError ( <EOL> "<STR_LIT>" . format ( <EOL> collapseuser ( source ) , collapseuser ( target ) <EOL> ) <EOL> ) <EOL> def _has_xcode_tools ( self ) : <EOL> developer_dir = spawn ( [ "<STR_LIT>" , "<STR_LIT>" ] , <EOL> check_output = True , <EOL> debug = self . debug , <EOL> env = self . env ) . strip ( ) <EOL> return bool ( os . path . isdir ( developer_dir ) and os . path . exists ( <EOL> os . path . join ( developer_dir , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" ) <EOL> ) ) <EOL> def _assert_requirements ( self ) : <EOL> macos_version = platform . mac_ver ( ) [ <NUM_LIT:0> ] <EOL> if int ( macos_version . split ( "<STR_LIT:.>" ) [ <NUM_LIT:1> ] ) < <NUM_LIT:9> : <EOL> raise UnsupportedOSError ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" , <EOL> macos_version <EOL> ) <EOL> if not self . _has_xcode_tools ( ) : <EOL> print ( tty . progress ( "<STR_LIT>" <EOL> "<STR_LIT>" ) ) <EOL> spawn ( [ "<STR_LIT>" , "<STR_LIT>" ] , <EOL> debug = self . debug , env = self . env ) <EOL> click . pause ( "<STR_LIT>" ) <EOL> if not self . _has_xcode_tools ( ) : <EOL> raise XcodeMissingError ( <EOL> "<STR_LIT>" , <EOL> ) <EOL> if spawn ( [ "<STR_LIT>" , "<STR_LIT>" ] , check_call = False , debug = self . debug , <EOL> stdout = subprocess . PIPE , <EOL> stderr = subprocess . PIPE , <EOL> env = self . env ) : <EOL> raise BrewMissingError ( <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" <EOL> ) <EOL> @ staticmethod <EOL> def _islinkkey ( symlink , stow ) : <EOL> return symlink == stow or symlink . startswith ( os . path . join ( stow , "<STR_LIT>" ) ) <EOL> def restore ( self , ignore_errors = None ) : <EOL> ignore_errors = ignore_errors if ignore_errors is not None else False <EOL> self . _assert_requirements ( ) <EOL> caskbrew = Brew ( True , self . debug , self . verbose ) <EOL> homebrew = Brew ( False , self . debug , self . verbose ) <EOL> bootstrap = self . read_bootstrap ( ) <EOL> casks = bootstrap . get ( "<STR_LIT>" , [ ] ) <EOL> dependencies = bootstrap . get ( "<STR_LIT>" , { } ) <EOL> self . run_scripts ( before = True ) <EOL> for tap in bootstrap . get ( "<STR_LIT>" , [ ] ) : <EOL> homebrew . tap ( tap ) <EOL> outdated = homebrew . outdated ( ) <EOL> for formula in bootstrap . get ( "<STR_LIT>" , [ ] ) : <EOL> if formula in dependencies : <EOL> deps = dependencies [ formula ] <EOL> deps = deps if isinstance ( deps , list ) else [ deps ] <EOL> deps = ( dep for dep in deps if dep . startswith ( "<STR_LIT>" ) ) <EOL> for dep in deps : <EOL> cask = dep . split ( "<STR_LIT:/>" ) [ <NUM_LIT:1> ] <EOL> print ( tty . progress ( <EOL> "<STR_LIT>" ) . format ( <EOL> cask , formula <EOL> ) <EOL> ) <EOL> caskbrew . safe_install ( cask , ignore_errors ) <EOL> del casks [ casks . index ( cask ) ] <EOL> homebrew . safe_install ( formula , ignore_errors , formula in outdated ) <EOL> for cask in casks : <EOL> caskbrew . safe_install ( cask , ignore_errors ) <EOL> self . relink ( ) <EOL> self . apply_defaults ( ) <EOL> self . apply_icons ( ) <EOL> self . run_scripts ( after = True ) <EOL> def install ( self , * formulas , ** kwargs ) : <EOL> formulas = list ( formulas ) or [ ] <EOL> force = kwargs . get ( "<STR_LIT>" , False ) <EOL> self . brew . install ( * formulas , force = force ) <EOL> self . add_to_bootstrap ( formulas ) <EOL> def add_to_bootstrap ( self , formulas ) : <EOL> def transform ( formula ) : <EOL> return lambda x : x + [ formula ] if formula not in x else x <EOL> for formula in formulas : <EOL> if self . _modify_bootstrap ( <EOL> "<STR_LIT>" if self . cask else "<STR_LIT>" , <EOL> transform = transform ( formula ) , <EOL> fallback = [ ] <EOL> ) : <EOL> tty . puts ( "<STR_LIT>" . format ( formula ) ) <EOL> else : <EOL> tty . puterr ( "<STR_LIT>" . format ( <EOL> formula <EOL> ) , warning = True ) <EOL> def rm ( self , * formulas ) : <EOL> def transform ( formula ) : <EOL> return lambda xs : [ x for x in xs if x != formula ] <EOL> formulas = list ( formulas ) or [ ] <EOL> self . brew . rm ( * formulas ) <EOL> for formula in formulas : <EOL> if self . _modify_bootstrap ( <EOL> "<STR_LIT>" if self . cask else "<STR_LIT>" , <EOL> transform = transform ( formula ) , <EOL> fallback = [ ] <EOL> ) : <EOL> tty . puts ( "<STR_LIT>" . format ( formula ) ) <EOL> else : <EOL> tty . puterr ( "<STR_LIT>" . format ( formula ) ) <EOL> def tap ( self , tap ) : <EOL> if tap is None : <EOL> tapped = self . tapped ( ) <EOL> if tapped : <EOL> print ( "<STR_LIT:\n>" . join ( tapped ) ) <EOL> else : <EOL> self . brew . tap ( tap ) <EOL> self . add_taps ( [ tap ] ) <EOL> def add_taps ( self , taps ) : <EOL> def transform ( tap ) : <EOL> return lambda x : x + [ tap ] if tap not in x else x <EOL> for tap in taps : <EOL> if self . _modify_bootstrap ( <EOL> "<STR_LIT>" , <EOL> transform = transform ( tap ) , <EOL> fallback = [ ] <EOL> ) : <EOL> tty . puts ( "<STR_LIT>" . format ( tap ) ) <EOL> else : <EOL> tty . puterr ( "<STR_LIT>" . format ( tap ) ) <EOL> def untap ( self , tap ) : <EOL> self . brew . untap ( tap ) <EOL> if self . _modify_bootstrap ( <EOL> "<STR_LIT>" , <EOL> transform = lambda xs : [ x for x in xs if x != tap ] , <EOL> fallback = [ ] <EOL> ) : <EOL> tty . puts ( "<STR_LIT>" . format ( tap ) ) <EOL> else : <EOL> tty . puterr ( "<STR_LIT>" . format ( tap ) ) <EOL> @ staticmethod <EOL> def expandtarget ( source , target ) : <EOL> expanded = os . path . expanduser ( target ) <EOL> if isdirname ( target ) : <EOL> return os . path . join ( expanded , os . path . basename ( source ) ) <EOL> return expanded <EOL> def expandtargets ( self , source_glob , target ) : <EOL> if not isdirname ( target ) and ( "<STR_LIT:*>" in source_glob or <EOL> "<STR_LIT:?>" in source_glob ) : <EOL> raise SymlinkError ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" . format ( source_glob , target ) <EOL> ) <EOL> mkdir_p ( os . path . dirname ( os . path . expanduser ( target ) ) ) <EOL> sources = iglob ( os . path . join ( self . symlink_dir , source_glob ) ) <EOL> expanded = [ ] <EOL> for source in sources : <EOL> source = os . path . join ( self . cider_dir , source ) <EOL> source_target = self . expandtarget ( source , target ) <EOL> expanded . append ( ( source , source_target ) ) <EOL> return expanded <EOL> def relink ( self , force = None ) : <EOL> force = force if force is not None else False <EOL> symlinks = self . read_bootstrap ( ) . get ( "<STR_LIT>" , { } ) <EOL> old_targets = self . _cached_targets ( ) <EOL> new_targets = [ ] <EOL> for source_glob , target in symlinks . items ( ) : <EOL> for source , expanded_target in self . expandtargets ( source_glob , <EOL> target ) : <EOL> if self . mklink ( source , expanded_target , force ) : <EOL> new_targets . append ( expanded_target ) <EOL> self . _remove_dead_targets ( set ( old_targets ) - set ( new_targets ) ) <EOL> self . _update_target_cache ( new_targets ) <EOL> return new_targets <EOL> def mklink ( self , source , target , force = None ) : <EOL> linked = False <EOL> if not os . path . exists ( source ) : <EOL> raise SymlinkError ( <EOL> "<STR_LIT>" . format ( <EOL> collapseuser ( source ) <EOL> ) <EOL> ) <EOL> try : <EOL> os . symlink ( source , target ) <EOL> linked = True <EOL> tty . puts ( "<STR_LIT>" . format ( <EOL> tty . color ( collapseuser ( target ) , tty . MAGENTA ) , <EOL> collapseuser ( source ) <EOL> ) ) <EOL> except OSError as e : <EOL> if e . errno != errno . EEXIST : <EOL> raise <EOL> if os . path . islink ( target ) : <EOL> if os . path . samefile ( <EOL> os . path . realpath ( target ) , <EOL> os . path . realpath ( source ) <EOL> ) : <EOL> linked = True <EOL> tty . putdebug ( "<STR_LIT>" . format ( <EOL> tty . color ( collapseuser ( target ) , tty . MAGENTA ) , <EOL> collapseuser ( source ) <EOL> ) , self . debug ) <EOL> else : <EOL> fmt = "<STR_LIT>" <EOL> tty . puterr ( fmt . format ( <EOL> tty . color ( target , tty . MAGENTA ) , <EOL> os . path . realpath ( collapseuser ( target ) ) , <EOL> os . path . realpath ( collapseuser ( source ) ) <EOL> ) , warning = force ) <EOL> else : <EOL> tty . puterr ( "<STR_LIT>" . format ( <EOL> collapseuser ( source ) , <EOL> collapseuser ( target ) <EOL> ) , warning = force ) <EOL> if not linked and force : <EOL> try : <EOL> osx . move_to_trash ( target ) <EOL> print ( tty . progress ( "<STR_LIT>" ) . format ( target ) ) <EOL> except OSError as e : <EOL> tty . puterr ( "<STR_LIT>" . format ( <EOL> target , str ( e ) ) <EOL> ) <EOL> return False <EOL> return self . mklink ( source , target , force ) <EOL> return linked <EOL> def installed ( self , prefix = None ) : <EOL> bootstrap = self . read_bootstrap ( ) <EOL> key = "<STR_LIT>" if self . cask else "<STR_LIT>" <EOL> formulas = bootstrap . get ( key , [ ] ) <EOL> if prefix : <EOL> return [ x for x in formulas if x . startswith ( prefix ) ] <EOL> return formulas <EOL> def tapped ( self ) : <EOL> return self . read_bootstrap ( ) . get ( "<STR_LIT>" , [ ] ) <EOL> def missing ( self ) : <EOL> installed = [ item . split ( ) [ <NUM_LIT:0> ] . strip ( ) for item in self . installed ( ) ] <EOL> brewed = self . brew . ls ( ) <EOL> def brew_orphan ( formula ) : <EOL> if formula . startswith ( "<STR_LIT>" ) : <EOL> return False <EOL> uses = self . brew . uses ( formula ) <EOL> return len ( set ( installed ) & set ( uses ) ) == <NUM_LIT:0> <EOL> return sorted ( filter ( brew_orphan , set ( brewed ) - set ( installed ) ) ) <EOL> def missing_taps ( self ) : <EOL> bootstrapped = self . tapped ( ) <EOL> brewed = self . brew . tap ( ) . strip ( ) . splitlines ( ) <EOL> return sorted ( set ( brewed ) - set ( bootstrapped ) ) <EOL> def ls ( self , formula ) : <EOL> formulas = self . installed ( formula ) <EOL> if formulas : <EOL> print ( "<STR_LIT:\n>" . join ( formulas ) ) <EOL> else : <EOL> tty . puterr ( "<STR_LIT>" , prefix = "<STR_LIT>" ) <EOL> def list_missing ( self ) : <EOL> missing_items = self . missing ( ) <EOL> if missing_items : <EOL> suffix = "<STR_LIT:s>" if len ( missing_items ) != <NUM_LIT:1> else "<STR_LIT>" <EOL> fmt = "<STR_LIT>" + "<STR_LIT>" <EOL> tty . puterr ( fmt . format ( len ( missing_items ) , suffix ) , warning = True ) <EOL> print ( "<STR_LIT:\n>" . join ( missing_items ) + "<STR_LIT:\n>" ) <EOL> if prompt ( "<STR_LIT>" ) : <EOL> self . add_to_bootstrap ( missing_items ) <EOL> else : <EOL> print ( "<STR_LIT>" ) <EOL> def list_missing_taps ( self ) : <EOL> missing_taps = self . missing_taps ( ) <EOL> if missing_taps : <EOL> suffix = "<STR_LIT:s>" if len ( missing_taps ) != <NUM_LIT:1> else "<STR_LIT>" <EOL> fmt = "<STR_LIT>" <EOL> tty . puterr ( fmt . format ( len ( missing_taps ) , suffix ) , warning = True ) <EOL> print ( "<STR_LIT:\n>" . join ( missing_taps ) + "<STR_LIT:\n>" ) <EOL> if prompt ( "<STR_LIT>" ) : <EOL> self . add_taps ( missing_taps ) <EOL> else : <EOL> print ( "<STR_LIT>" ) <EOL> @ staticmethod <EOL> def json_value ( value ) : <EOL> if isinstance ( value , str ) or isinstance ( value , unicode ) : <EOL> try : <EOL> return json . loads ( _DEFAULTS_FALSE_RE . sub ( <EOL> "<STR_LIT:false>" , <EOL> _DEFAULTS_TRUE_RE . sub ( "<STR_LIT:true>" , value ) <EOL> ) ) <EOL> except ValueError : <EOL> pass <EOL> return value <EOL> def set_default ( self , domain , key , value , force = None ) : <EOL> json_value = self . json_value ( value ) <EOL> self . defaults . write ( domain , key , json_value , force ) <EOL> def transform ( defaults ) : <EOL> defaults [ key ] = json_value <EOL> return defaults <EOL> if self . _modify_defaults ( domain , transform ) : <EOL> tty . puts ( "<STR_LIT>" ) <EOL> def remove_default ( self , domain , key ) : <EOL> self . defaults . delete ( domain , key ) <EOL> def transform ( defaults ) : <EOL> defaults . pop ( key , None ) <EOL> return defaults <EOL> if self . _modify_defaults ( domain , transform ) : <EOL> tty . puts ( "<STR_LIT>" ) <EOL> def apply_defaults ( self ) : <EOL> defaults = self . read_defaults ( ) <EOL> for domain , options in defaults . items ( ) : <EOL> for key , value in options . items ( ) : <EOL> self . defaults . write ( domain , key , value ) <EOL> tty . puts ( "<STR_LIT>" ) <EOL> def run_scripts ( self , before = None , after = None ) : <EOL> bootstrap = self . read_bootstrap ( ) <EOL> scripts = [ ] <EOL> scripts += bootstrap . get ( "<STR_LIT>" , [ ] ) if before else [ ] <EOL> scripts += bootstrap . get ( "<STR_LIT>" , [ ] ) if after else [ ] <EOL> for script in scripts : <EOL> spawn ( [ script ] , shell = True , debug = self . debug , <EOL> cwd = self . cider_dir , env = self . env ) <EOL> def set_icon ( self , app , icon ) : <EOL> def transform ( icons ) : <EOL> icons [ app ] = icon <EOL> return icons <EOL> self . _modify_bootstrap ( "<STR_LIT>" , transform , { } ) <EOL> _apply_icon ( app , icon ) <EOL> def remove_icon ( self , app ) : <EOL> def transform ( icons ) : <EOL> if icons : <EOL> del icons [ app ] <EOL> return icons <EOL> app_path = osx . path_for_app ( app ) <EOL> if not app_path : <EOL> raise AppMissingError ( "<STR_LIT>" . format ( app ) ) <EOL> self . _modify_bootstrap ( "<STR_LIT>" , transform ) <EOL> osx . remove_icon ( app_path ) <EOL> def apply_icons ( self ) : <EOL> bootstrap = read_config ( self . bootstrap_file ) <EOL> icons = bootstrap . get ( "<STR_LIT>" , { } ) <EOL> for app , icon in icons . items ( ) : <EOL> _apply_icon ( app , icon ) <EOL> tty . puts ( "<STR_LIT>" ) <EOL> def add_symlink ( self , name , target ) : <EOL> target = collapseuser ( os . path . normpath ( target ) ) <EOL> target_dir = os . path . dirname ( target ) <EOL> if target_dir != "<STR_LIT>" : <EOL> target_dir = os . path . join ( target_dir , "<STR_LIT>" ) <EOL> def transform ( symlinks ) : <EOL> for key in symlinks : <EOL> if ( os . path . dirname ( key ) == name and <EOL> fnmatch ( os . path . basename ( target ) , os . path . basename ( key ) ) ) : <EOL> return symlinks <EOL> dotted = os . path . basename ( target ) . startswith ( "<STR_LIT:.>" ) <EOL> pattern = "<STR_LIT>" . format ( name , "<STR_LIT:.>" if dotted else "<STR_LIT>" ) <EOL> symlinks [ pattern ] = target_dir <EOL> return symlinks <EOL> return self . _modify_bootstrap ( "<STR_LIT>" , transform , { } ) <EOL> def remove_symlink ( self , name ) : <EOL> def transform ( symlinks ) : <EOL> if symlinks : <EOL> for key in symlinks . keys ( ) : <EOL> if self . _islinkkey ( key , name ) : <EOL> del symlinks [ key ] <EOL> return symlinks <EOL> return self . _modify_bootstrap ( "<STR_LIT>" , transform ) <EOL> def addlink ( self , name , * items ) : <EOL> for item in items : <EOL> stow_path = os . path . join ( self . symlink_dir , name ) <EOL> stow_fpath = os . path . join ( stow_path , os . path . basename ( item ) ) <EOL> if not os . path . exists ( item ) : <EOL> raise StowError ( <EOL> "<STR_LIT>" . format ( <EOL> collapseuser ( item ) <EOL> ) <EOL> ) <EOL> samefile = os . path . exists ( stow_fpath ) and os . path . samefile ( <EOL> os . path . realpath ( stow_fpath ) , os . path . realpath ( item ) <EOL> ) <EOL> if os . path . exists ( stow_fpath ) and not samefile : <EOL> raise StowError ( "<STR_LIT>" . format ( <EOL> collapseuser ( stow_fpath ) <EOL> ) ) <EOL> if not samefile : <EOL> mkdir_p ( stow_path ) <EOL> shutil . move ( item , stow_path ) <EOL> target = os . path . abspath ( item ) <EOL> self . add_symlink ( name , target ) <EOL> self . mklink ( stow_fpath , target ) <EOL> self . _update_target_cache ( self . _cached_targets ( ) + [ target ] ) <EOL> def unlink ( self , name ) : <EOL> symlinks = self . read_bootstrap ( ) . get ( "<STR_LIT>" , { } ) <EOL> removed_targets = set ( ) <EOL> found = False <EOL> for source_glob , target in symlinks . items ( ) : <EOL> if self . _islinkkey ( source_glob , name ) : <EOL> found = True <EOL> for source , target in self . expandtargets ( source_glob , target ) : <EOL> self . _remove_link_target ( source , target ) <EOL> removed_targets . add ( target ) <EOL> shutil . move ( source , target ) <EOL> print ( tty . progress ( "<STR_LIT>" . format ( <EOL> collapseuser ( source ) , <EOL> collapseuser ( target ) <EOL> ) ) ) <EOL> if not found : <EOL> raise StowError ( "<STR_LIT>" . format ( name ) ) <EOL> try : <EOL> os . rmdir ( os . path . join ( self . symlink_dir , name ) ) <EOL> except OSError as e : <EOL> if e . errno != errno . ENOTEMPTY : <EOL> raise e <EOL> self . remove_symlink ( name ) <EOL> self . _update_target_cache ( <EOL> set ( self . _cached_targets ( ) ) - removed_targets <EOL> ) <EOL> def _apply_icon ( app , icon ) : <EOL> app_path = osx . path_for_app ( app ) <EOL> if not app_path : <EOL> raise AppMissingError ( "<STR_LIT>" . format ( app ) ) <EOL> try : <EOL> components = urlparse ( icon ) <EOL> if not components [ "<STR_LIT>" ] or components [ '<STR_LIT>' ] == "<STR_LIT:file>" : <EOL> icon_path = components [ "<STR_LIT:path>" ] <EOL> else : <EOL> tmpdir = mkdtemp ( ) <EOL> icon_path = os . path . join ( tmpdir , <EOL> os . path . basename ( components [ "<STR_LIT:path>" ] ) ) <EOL> print ( tty . progress ( "<STR_LIT>" . format ( app , icon ) ) ) <EOL> curl ( icon , icon_path ) <EOL> except ValueError : <EOL> icon_path = icon <EOL> osx . set_icon ( app_path , os . path . expanduser ( icon_path ) ) </s>
