<s> '''<STR_LIT>''' <EOL> from __future__ import absolute_import , print_function <EOL> import os <EOL> import yaml <EOL> import tarfile <EOL> import shutil <EOL> import msgpack <EOL> import datetime <EOL> import hashlib <EOL> import logging <EOL> import pwd <EOL> import grp <EOL> import sys <EOL> import salt . config <EOL> import salt . loader <EOL> import salt . utils <EOL> import salt . utils . http as http <EOL> import salt . syspaths as syspaths <EOL> import salt . ext . six as six <EOL> from salt . ext . six import string_types <EOL> from salt . ext . six . moves import input <EOL> from salt . ext . six . moves import zip <EOL> from salt . ext . six . moves import filter <EOL> log = logging . getLogger ( __name__ ) <EOL> class SPMException ( Exception ) : <EOL> '''<STR_LIT>''' <EOL> class SPMInvocationError ( SPMException ) : <EOL> '''<STR_LIT>''' <EOL> class SPMPackageError ( SPMException ) : <EOL> '''<STR_LIT>''' <EOL> class SPMDatabaseError ( SPMException ) : <EOL> '''<STR_LIT>''' <EOL> class SPMOperationCanceled ( SPMException ) : <EOL> '''<STR_LIT>''' <EOL> class SPMClient ( object ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , ui , opts = None ) : <EOL> self . ui = ui <EOL> if not opts : <EOL> opts = salt . config . spm_config ( <EOL> os . path . join ( syspaths . CONFIG_DIR , '<STR_LIT>' ) <EOL> ) <EOL> self . opts = opts <EOL> self . db_prov = self . opts . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> self . files_prov = self . opts . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> self . _prep_pkgdb ( ) <EOL> self . _prep_pkgfiles ( ) <EOL> self . _init ( ) <EOL> def _prep_pkgdb ( self ) : <EOL> self . pkgdb = salt . loader . pkgdb ( self . opts ) <EOL> def _prep_pkgfiles ( self ) : <EOL> self . pkgfiles = salt . loader . pkgfiles ( self . opts ) <EOL> def _init ( self ) : <EOL> self . db_conn = self . _pkgdb_fun ( '<STR_LIT>' ) <EOL> self . files_conn = self . _pkgfiles_fun ( '<STR_LIT>' ) <EOL> def run ( self , args ) : <EOL> '''<STR_LIT>''' <EOL> command = args [ <NUM_LIT:0> ] <EOL> try : <EOL> if command == '<STR_LIT>' : <EOL> self . _install ( args ) <EOL> elif command == '<STR_LIT>' : <EOL> self . _local ( args ) <EOL> elif command == '<STR_LIT>' : <EOL> self . _remove ( args ) <EOL> elif command == '<STR_LIT>' : <EOL> self . _build ( args ) <EOL> elif command == '<STR_LIT>' : <EOL> self . _download_repo_metadata ( args ) <EOL> elif command == '<STR_LIT>' : <EOL> self . _create_repo ( args ) <EOL> elif command == '<STR_LIT>' : <EOL> self . _list_files ( args ) <EOL> elif command == '<STR_LIT:info>' : <EOL> self . _info ( args ) <EOL> else : <EOL> raise SPMInvocationError ( '<STR_LIT>' . format ( command ) ) <EOL> except SPMException as exc : <EOL> self . ui . error ( str ( exc ) ) <EOL> def _pkgdb_fun ( self , func , * args , ** kwargs ) : <EOL> try : <EOL> return getattr ( getattr ( self . pkgdb , self . db_prov ) , func ) ( * args , ** kwargs ) <EOL> except AttributeError : <EOL> return self . pkgdb [ '<STR_LIT>' . format ( self . db_prov , func ) ] ( * args , ** kwargs ) <EOL> def _pkgfiles_fun ( self , func , * args , ** kwargs ) : <EOL> try : <EOL> return getattr ( getattr ( self . pkgfiles , self . files_prov ) , func ) ( * args , ** kwargs ) <EOL> except AttributeError : <EOL> return self . pkgfiles [ '<STR_LIT>' . format ( self . files_prov , func ) ] ( * args , ** kwargs ) <EOL> def _local ( self , args ) : <EOL> '''<STR_LIT>''' <EOL> args . pop ( <NUM_LIT:0> ) <EOL> command = args [ <NUM_LIT:0> ] <EOL> if command == '<STR_LIT>' : <EOL> self . _local_install ( args ) <EOL> elif command == '<STR_LIT>' : <EOL> self . _local_list_files ( args ) <EOL> elif command == '<STR_LIT:info>' : <EOL> self . _local_info ( args ) <EOL> else : <EOL> raise SPMInvocationError ( '<STR_LIT>' . format ( command ) ) <EOL> def _install ( self , args ) : <EOL> '''<STR_LIT>''' <EOL> if len ( args ) < <NUM_LIT:2> : <EOL> raise SPMInvocationError ( '<STR_LIT>' ) <EOL> packages = args [ <NUM_LIT:1> : ] <EOL> file_map = { } <EOL> optional = [ ] <EOL> recommended = [ ] <EOL> to_install = [ ] <EOL> for pkg in packages : <EOL> if pkg . endswith ( '<STR_LIT>' ) : <EOL> if self . _pkgfiles_fun ( '<STR_LIT>' , pkg ) : <EOL> comps = pkg . split ( '<STR_LIT:->' ) <EOL> comps = '<STR_LIT:->' . join ( comps [ : - <NUM_LIT:2> ] ) . split ( '<STR_LIT:/>' ) <EOL> pkg_name = comps [ - <NUM_LIT:1> ] <EOL> formula_tar = tarfile . open ( pkg , '<STR_LIT>' ) <EOL> formula_ref = formula_tar . extractfile ( '<STR_LIT>' . format ( pkg_name ) ) <EOL> formula_def = yaml . safe_load ( formula_ref ) <EOL> file_map [ pkg_name ] = pkg <EOL> to_ , op_ , re_ = self . _check_all_deps ( <EOL> pkg_name = pkg_name , <EOL> pkg_file = pkg , <EOL> formula_def = formula_def <EOL> ) <EOL> to_install . extend ( to_ ) <EOL> optional . extend ( op_ ) <EOL> recommended . extend ( re_ ) <EOL> else : <EOL> raise SPMInvocationError ( '<STR_LIT>' . format ( pkg ) ) <EOL> else : <EOL> to_ , op_ , re_ = self . _check_all_deps ( pkg_name = pkg ) <EOL> to_install . extend ( to_ ) <EOL> optional . extend ( op_ ) <EOL> recommended . extend ( re_ ) <EOL> optional = set ( filter ( len , optional ) ) <EOL> self . ui . status ( '<STR_LIT>' . format ( <EOL> '<STR_LIT>' . join ( optional ) <EOL> ) ) <EOL> recommended = set ( filter ( len , recommended ) ) <EOL> self . ui . status ( '<STR_LIT>' . format ( <EOL> '<STR_LIT>' . join ( recommended ) <EOL> ) ) <EOL> to_install = set ( filter ( len , to_install ) ) <EOL> msg = '<STR_LIT>' . format ( '<STR_LIT>' . join ( to_install ) ) <EOL> if not self . opts [ '<STR_LIT>' ] : <EOL> self . ui . confirm ( msg ) <EOL> repo_metadata = self . _get_repo_metadata ( ) <EOL> for package in to_install : <EOL> if package in file_map : <EOL> self . _install_indv_pkg ( package , file_map [ package ] ) <EOL> else : <EOL> for repo in repo_metadata : <EOL> repo_info = repo_metadata [ repo ] <EOL> if package in repo_metadata [ repo ] [ '<STR_LIT>' ] : <EOL> cache_path = '<STR_LIT>' . format ( <EOL> self . opts [ '<STR_LIT>' ] , <EOL> repo <EOL> ) <EOL> dl_path = '<STR_LIT>' . format ( <EOL> repo_info [ '<STR_LIT:info>' ] [ '<STR_LIT:url>' ] , <EOL> repo_info [ '<STR_LIT>' ] [ package ] [ '<STR_LIT:filename>' ] <EOL> ) <EOL> out_file = '<STR_LIT>' . format ( <EOL> cache_path , <EOL> repo_info [ '<STR_LIT>' ] [ package ] [ '<STR_LIT:filename>' ] <EOL> ) <EOL> if not os . path . exists ( cache_path ) : <EOL> os . makedirs ( cache_path ) <EOL> if dl_path . startswith ( '<STR_LIT>' ) : <EOL> dl_path = dl_path . replace ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> shutil . copyfile ( dl_path , out_file ) <EOL> else : <EOL> http . query ( dl_path , text_out = out_file ) <EOL> self . _install_indv_pkg ( package , out_file ) <EOL> return <EOL> def _local_install ( self , args , pkg_name = None ) : <EOL> '''<STR_LIT>''' <EOL> if len ( args ) < <NUM_LIT:2> : <EOL> raise SPMInvocationError ( '<STR_LIT>' ) <EOL> self . _install ( args ) <EOL> def _check_all_deps ( self , pkg_name = None , pkg_file = None , formula_def = None ) : <EOL> '''<STR_LIT>''' <EOL> if pkg_file and not os . path . exists ( pkg_file ) : <EOL> raise SPMInvocationError ( '<STR_LIT>' . format ( pkg_file ) ) <EOL> self . repo_metadata = self . _get_repo_metadata ( ) <EOL> if not formula_def : <EOL> for repo in self . repo_metadata : <EOL> if not isinstance ( self . repo_metadata [ repo ] [ '<STR_LIT>' ] , dict ) : <EOL> continue <EOL> if pkg_name in self . repo_metadata [ repo ] [ '<STR_LIT>' ] : <EOL> formula_def = self . repo_metadata [ repo ] [ '<STR_LIT>' ] [ pkg_name ] [ '<STR_LIT:info>' ] <EOL> if not formula_def : <EOL> raise SPMInvocationError ( '<STR_LIT>' . format ( pkg_name ) ) <EOL> pkg_info = self . _pkgdb_fun ( '<STR_LIT:info>' , pkg_name , self . db_conn ) <EOL> pkgs_to_install = [ ] <EOL> if pkg_info is None or self . opts [ '<STR_LIT>' ] : <EOL> pkgs_to_install . append ( pkg_name ) <EOL> elif pkg_info is not None and not self . opts [ '<STR_LIT>' ] : <EOL> raise SPMPackageError ( <EOL> '<STR_LIT>' . format ( formula_def [ '<STR_LIT:name>' ] ) <EOL> ) <EOL> optional_install = [ ] <EOL> recommended_install = [ ] <EOL> if '<STR_LIT>' in formula_def or '<STR_LIT>' in formula_def or '<STR_LIT>' in formula_def : <EOL> self . avail_pkgs = { } <EOL> for repo in self . repo_metadata : <EOL> if not isinstance ( self . repo_metadata [ repo ] [ '<STR_LIT>' ] , dict ) : <EOL> continue <EOL> for pkg in self . repo_metadata [ repo ] [ '<STR_LIT>' ] : <EOL> self . avail_pkgs [ pkg ] = repo <EOL> needs , unavail , optional , recommended = self . _resolve_deps ( formula_def ) <EOL> if len ( unavail ) > <NUM_LIT:0> : <EOL> raise SPMPackageError ( <EOL> '<STR_LIT>' . format ( <EOL> formula_def [ '<STR_LIT:name>' ] , '<STR_LIT:\n>' . join ( unavail ) ) <EOL> ) <EOL> if optional : <EOL> optional_install . extend ( optional ) <EOL> for dep_pkg in optional : <EOL> pkg_info = self . _pkgdb_fun ( '<STR_LIT:info>' , formula_def [ '<STR_LIT:name>' ] ) <EOL> msg = dep_pkg <EOL> if isinstance ( pkg_info , dict ) : <EOL> msg = '<STR_LIT>' . format ( dep_pkg ) <EOL> optional_install . append ( msg ) <EOL> if recommended : <EOL> recommended_install . extend ( recommended ) <EOL> for dep_pkg in recommended : <EOL> pkg_info = self . _pkgdb_fun ( '<STR_LIT:info>' , formula_def [ '<STR_LIT:name>' ] ) <EOL> msg = dep_pkg <EOL> if isinstance ( pkg_info , dict ) : <EOL> msg = '<STR_LIT>' . format ( dep_pkg ) <EOL> recommended_install . append ( msg ) <EOL> if needs : <EOL> pkgs_to_install . extend ( needs ) <EOL> for dep_pkg in needs : <EOL> pkg_info = self . _pkgdb_fun ( '<STR_LIT:info>' , formula_def [ '<STR_LIT:name>' ] ) <EOL> msg = dep_pkg <EOL> if isinstance ( pkg_info , dict ) : <EOL> msg = '<STR_LIT>' . format ( dep_pkg ) <EOL> return pkgs_to_install , optional_install , recommended_install <EOL> def _install_indv_pkg ( self , pkg_name , pkg_file ) : <EOL> '''<STR_LIT>''' <EOL> self . ui . status ( '<STR_LIT>' . format ( pkg_name ) ) <EOL> formula_tar = tarfile . open ( pkg_file , '<STR_LIT>' ) <EOL> formula_ref = formula_tar . extractfile ( '<STR_LIT>' . format ( pkg_name ) ) <EOL> formula_def = yaml . safe_load ( formula_ref ) <EOL> for field in ( '<STR_LIT:version>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:description>' ) : <EOL> if field not in formula_def : <EOL> raise SPMPackageError ( '<STR_LIT>' . format ( field ) ) <EOL> pkg_files = formula_tar . getmembers ( ) <EOL> existing_files = self . _pkgfiles_fun ( '<STR_LIT>' , pkg_name , pkg_files , formula_def ) <EOL> if existing_files and not self . opts [ '<STR_LIT>' ] : <EOL> raise SPMPackageError ( '<STR_LIT>' . format ( <EOL> pkg_name , '<STR_LIT:\n>' . join ( existing_files ) ) <EOL> ) <EOL> self . _pkgdb_fun ( '<STR_LIT>' , pkg_name , formula_def , self . db_conn ) <EOL> uid = self . opts . get ( '<STR_LIT>' , os . getuid ( ) ) <EOL> gid = self . opts . get ( '<STR_LIT>' , os . getgid ( ) ) <EOL> uname = pwd . getpwuid ( uid ) [ <NUM_LIT:0> ] <EOL> gname = grp . getgrgid ( gid ) [ <NUM_LIT:0> ] <EOL> for member in pkg_files : <EOL> member . uid = uid <EOL> member . gid = gid <EOL> member . uname = uname <EOL> member . gname = gname <EOL> out_path = self . _pkgfiles_fun ( '<STR_LIT>' , <EOL> pkg_name , <EOL> formula_tar , <EOL> member , <EOL> formula_def , <EOL> self . files_conn ) <EOL> if out_path is not False : <EOL> if member . isdir ( ) : <EOL> digest = '<STR_LIT>' <EOL> else : <EOL> self . _verbose ( '<STR_LIT>' . format ( member . name , out_path ) , log . trace ) <EOL> file_hash = hashlib . sha1 ( ) <EOL> digest = self . _pkgfiles_fun ( '<STR_LIT>' , <EOL> os . path . join ( out_path , member . name ) , <EOL> file_hash , <EOL> self . files_conn ) <EOL> self . _pkgdb_fun ( '<STR_LIT>' , <EOL> pkg_name , <EOL> member , <EOL> out_path , <EOL> digest , <EOL> self . db_conn ) <EOL> formula_tar . close ( ) <EOL> def _resolve_deps ( self , formula_def ) : <EOL> '''<STR_LIT>''' <EOL> pkg_info = self . pkgdb [ '<STR_LIT>' . format ( self . db_prov ) ] ( formula_def [ '<STR_LIT:name>' ] ) <EOL> if not isinstance ( pkg_info , dict ) : <EOL> pkg_info = { } <EOL> can_has = { } <EOL> cant_has = [ ] <EOL> if '<STR_LIT>' in formula_def and formula_def [ '<STR_LIT>' ] is None : <EOL> formula_def [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> for dep in formula_def . get ( '<STR_LIT>' , '<STR_LIT>' ) . split ( '<STR_LIT:U+002C>' ) : <EOL> dep = dep . strip ( ) <EOL> if not dep : <EOL> continue <EOL> if self . pkgdb [ '<STR_LIT>' . format ( self . db_prov ) ] ( dep ) : <EOL> continue <EOL> if dep in self . avail_pkgs : <EOL> can_has [ dep ] = self . avail_pkgs [ dep ] <EOL> else : <EOL> cant_has . append ( dep ) <EOL> optional = formula_def . get ( '<STR_LIT>' , '<STR_LIT>' ) . split ( '<STR_LIT:U+002C>' ) <EOL> recommended = formula_def . get ( '<STR_LIT>' , '<STR_LIT>' ) . split ( '<STR_LIT:U+002C>' ) <EOL> inspected = [ ] <EOL> to_inspect = can_has . copy ( ) <EOL> while len ( to_inspect ) > <NUM_LIT:0> : <EOL> dep = next ( six . iterkeys ( to_inspect ) ) <EOL> del to_inspect [ dep ] <EOL> if dep in inspected : <EOL> continue <EOL> inspected . append ( dep ) <EOL> repo_contents = self . repo_metadata . get ( can_has [ dep ] , { } ) <EOL> repo_packages = repo_contents . get ( '<STR_LIT>' , { } ) <EOL> dep_formula = repo_packages . get ( dep , { } ) . get ( '<STR_LIT:info>' , { } ) <EOL> also_can , also_cant , opt_dep , rec_dep = self . _resolve_deps ( dep_formula ) <EOL> can_has . update ( also_can ) <EOL> cant_has = sorted ( set ( cant_has + also_cant ) ) <EOL> optional = sorted ( set ( optional + opt_dep ) ) <EOL> recommended = sorted ( set ( recommended + rec_dep ) ) <EOL> return can_has , cant_has , optional , recommended <EOL> def _traverse_repos ( self , callback , repo_name = None ) : <EOL> '''<STR_LIT>''' <EOL> repo_files = [ ] <EOL> if os . path . exists ( self . opts [ '<STR_LIT>' ] ) : <EOL> repo_files . append ( self . opts [ '<STR_LIT>' ] ) <EOL> for ( dirpath , dirnames , filenames ) in os . walk ( '<STR_LIT>' . format ( self . opts [ '<STR_LIT>' ] ) ) : <EOL> for repo_file in filenames : <EOL> if not repo_file . endswith ( '<STR_LIT>' ) : <EOL> continue <EOL> repo_files . append ( repo_file ) <EOL> if not os . path . exists ( self . opts [ '<STR_LIT>' ] ) : <EOL> os . makedirs ( self . opts [ '<STR_LIT>' ] ) <EOL> for repo_file in repo_files : <EOL> repo_path = '<STR_LIT>' . format ( self . opts [ '<STR_LIT>' ] , repo_file ) <EOL> with salt . utils . fopen ( repo_path ) as rph : <EOL> repo_data = yaml . safe_load ( rph ) <EOL> for repo in repo_data : <EOL> if repo_data [ repo ] . get ( '<STR_LIT>' , True ) is False : <EOL> continue <EOL> if repo_name is not None and repo != repo_name : <EOL> continue <EOL> callback ( repo , repo_data [ repo ] ) <EOL> def _download_repo_metadata ( self , args ) : <EOL> '''<STR_LIT>''' <EOL> def _update_metadata ( repo , repo_info ) : <EOL> dl_path = '<STR_LIT>' . format ( repo_info [ '<STR_LIT:url>' ] ) <EOL> if dl_path . startswith ( '<STR_LIT>' ) : <EOL> dl_path = dl_path . replace ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> with salt . utils . fopen ( dl_path , '<STR_LIT:r>' ) as rpm : <EOL> metadata = yaml . safe_load ( rpm ) <EOL> else : <EOL> response = http . query ( dl_path , text = True ) <EOL> metadata = response . get ( '<STR_LIT:text>' , { } ) <EOL> cache_path = '<STR_LIT>' . format ( <EOL> self . opts [ '<STR_LIT>' ] , <EOL> repo <EOL> ) <EOL> with salt . utils . fopen ( cache_path , '<STR_LIT:w>' ) as cph : <EOL> msgpack . dump ( metadata , cph ) <EOL> repo_name = args [ <NUM_LIT:1> ] if len ( args ) > <NUM_LIT:1> else None <EOL> self . _traverse_repos ( _update_metadata , repo_name ) <EOL> def _get_repo_metadata ( self ) : <EOL> '''<STR_LIT>''' <EOL> metadata = { } <EOL> if not os . path . exists ( self . opts [ '<STR_LIT>' ] ) : <EOL> os . makedirs ( self . opts [ '<STR_LIT>' ] ) <EOL> def _read_metadata ( repo , repo_info ) : <EOL> cache_path = '<STR_LIT>' . format ( <EOL> self . opts [ '<STR_LIT>' ] , <EOL> repo <EOL> ) <EOL> if not os . path . exists ( cache_path ) : <EOL> raise SPMPackageError ( '<STR_LIT>' . format ( cache_path ) ) <EOL> with salt . utils . fopen ( cache_path , '<STR_LIT:r>' ) as cph : <EOL> metadata [ repo ] = { <EOL> '<STR_LIT:info>' : repo_info , <EOL> '<STR_LIT>' : msgpack . load ( cph ) , <EOL> } <EOL> self . _traverse_repos ( _read_metadata ) <EOL> return metadata <EOL> def _create_repo ( self , args ) : <EOL> '''<STR_LIT>''' <EOL> if len ( args ) < <NUM_LIT:2> : <EOL> raise SPMInvocationError ( '<STR_LIT>' ) <EOL> if args [ <NUM_LIT:1> ] == '<STR_LIT:.>' : <EOL> repo_path = os . environ [ '<STR_LIT>' ] <EOL> else : <EOL> repo_path = args [ <NUM_LIT:1> ] <EOL> repo_metadata = { } <EOL> for ( dirpath , dirnames , filenames ) in os . walk ( repo_path ) : <EOL> for spm_file in filenames : <EOL> if not spm_file . endswith ( '<STR_LIT>' ) : <EOL> continue <EOL> spm_path = '<STR_LIT>' . format ( repo_path , spm_file ) <EOL> if not tarfile . is_tarfile ( spm_path ) : <EOL> continue <EOL> comps = spm_file . split ( '<STR_LIT:->' ) <EOL> spm_name = '<STR_LIT:->' . join ( comps [ : - <NUM_LIT:2> ] ) <EOL> spm_fh = tarfile . open ( spm_path , '<STR_LIT>' ) <EOL> formula_handle = spm_fh . extractfile ( '<STR_LIT>' . format ( spm_name ) ) <EOL> formula_conf = yaml . safe_load ( formula_handle . read ( ) ) <EOL> repo_metadata [ spm_name ] = { <EOL> '<STR_LIT:info>' : formula_conf . copy ( ) , <EOL> } <EOL> repo_metadata [ spm_name ] [ '<STR_LIT:filename>' ] = spm_file <EOL> metadata_filename = '<STR_LIT>' . format ( repo_path ) <EOL> with salt . utils . fopen ( metadata_filename , '<STR_LIT:w>' ) as mfh : <EOL> yaml . dump ( repo_metadata , mfh , indent = <NUM_LIT:4> , canonical = False , default_flow_style = False ) <EOL> log . debug ( '<STR_LIT>' . format ( metadata_filename ) ) <EOL> def _remove ( self , args ) : <EOL> '''<STR_LIT>''' <EOL> if len ( args ) < <NUM_LIT:2> : <EOL> raise SPMInvocationError ( '<STR_LIT>' ) <EOL> packages = args [ <NUM_LIT:1> : ] <EOL> msg = '<STR_LIT>' . format ( '<STR_LIT>' . join ( packages ) ) <EOL> if not self . opts [ '<STR_LIT>' ] : <EOL> self . ui . confirm ( msg ) <EOL> for package in packages : <EOL> self . ui . status ( '<STR_LIT>' . format ( package ) ) <EOL> if not self . _pkgdb_fun ( '<STR_LIT>' , self . opts [ '<STR_LIT>' ] ) : <EOL> raise SPMDatabaseError ( '<STR_LIT>' . format ( self . opts [ '<STR_LIT>' ] , package ) ) <EOL> pkg_info = self . _pkgdb_fun ( '<STR_LIT:info>' , package , self . db_conn ) <EOL> if pkg_info is None : <EOL> raise SPMInvocationError ( '<STR_LIT>' . format ( package ) ) <EOL> files = self . _pkgdb_fun ( '<STR_LIT>' , package , self . db_conn ) <EOL> dirs = [ ] <EOL> for filerow in files : <EOL> if self . _pkgfiles_fun ( '<STR_LIT>' , filerow [ <NUM_LIT:0> ] ) : <EOL> dirs . append ( filerow [ <NUM_LIT:0> ] ) <EOL> continue <EOL> file_hash = hashlib . sha1 ( ) <EOL> digest = self . _pkgfiles_fun ( '<STR_LIT>' , filerow [ <NUM_LIT:0> ] , file_hash , self . files_conn ) <EOL> if filerow [ <NUM_LIT:1> ] == digest : <EOL> self . _verbose ( '<STR_LIT>' . format ( filerow [ <NUM_LIT:0> ] ) , log . trace ) <EOL> self . _pkgfiles_fun ( '<STR_LIT>' , filerow [ <NUM_LIT:0> ] , self . files_conn ) <EOL> else : <EOL> self . _verbose ( '<STR_LIT>' . format ( filerow [ <NUM_LIT:0> ] ) , log . trace ) <EOL> self . _pkgdb_fun ( '<STR_LIT>' , filerow [ <NUM_LIT:0> ] , package , self . db_conn ) <EOL> for dir_ in sorted ( dirs , reverse = True ) : <EOL> self . _pkgdb_fun ( '<STR_LIT>' , dir_ , package , self . db_conn ) <EOL> try : <EOL> self . _verbose ( '<STR_LIT>' . format ( dir_ ) , log . trace ) <EOL> os . rmdir ( dir_ ) <EOL> except OSError : <EOL> self . _verbose ( '<STR_LIT>' . format ( dir_ ) , log . trace ) <EOL> self . _pkgdb_fun ( '<STR_LIT>' , package , self . db_conn ) <EOL> def _verbose ( self , msg , level = log . debug ) : <EOL> '''<STR_LIT>''' <EOL> if self . opts . get ( '<STR_LIT>' , False ) is True : <EOL> self . ui . status ( msg ) <EOL> level ( msg ) <EOL> def _local_info ( self , args ) : <EOL> '''<STR_LIT>''' <EOL> if len ( args ) < <NUM_LIT:2> : <EOL> raise SPMInvocationError ( '<STR_LIT>' ) <EOL> pkg_file = args [ <NUM_LIT:1> ] <EOL> if not os . path . exists ( pkg_file ) : <EOL> raise SPMInvocationError ( '<STR_LIT>' . format ( pkg_file ) ) <EOL> comps = pkg_file . split ( '<STR_LIT:->' ) <EOL> comps = '<STR_LIT:->' . join ( comps [ : - <NUM_LIT:2> ] ) . split ( '<STR_LIT:/>' ) <EOL> name = comps [ - <NUM_LIT:1> ] <EOL> formula_tar = tarfile . open ( pkg_file , '<STR_LIT>' ) <EOL> formula_ref = formula_tar . extractfile ( '<STR_LIT>' . format ( name ) ) <EOL> formula_def = yaml . safe_load ( formula_ref ) <EOL> self . ui . status ( self . _get_info ( formula_def ) ) <EOL> def _info ( self , args ) : <EOL> '''<STR_LIT>''' <EOL> if len ( args ) < <NUM_LIT:2> : <EOL> raise SPMInvocationError ( '<STR_LIT>' ) <EOL> package = args [ <NUM_LIT:1> ] <EOL> pkg_info = self . _pkgdb_fun ( '<STR_LIT:info>' , package , self . db_conn ) <EOL> if pkg_info is None : <EOL> raise SPMPackageError ( '<STR_LIT>' . format ( package ) ) <EOL> self . ui . status ( self . _get_info ( pkg_info ) ) <EOL> def _get_info ( self , formula_def ) : <EOL> '''<STR_LIT>''' <EOL> fields = ( <EOL> '<STR_LIT:name>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT:version>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT:description>' , <EOL> ) <EOL> for item in fields : <EOL> if item not in formula_def : <EOL> formula_def [ item ] = '<STR_LIT:None>' <EOL> if '<STR_LIT>' not in formula_def : <EOL> formula_def [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> return ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) . format ( ** formula_def ) <EOL> def _local_list_files ( self , args ) : <EOL> '''<STR_LIT>''' <EOL> if len ( args ) < <NUM_LIT:2> : <EOL> raise SPMInvocationError ( '<STR_LIT>' ) <EOL> pkg_file = args [ <NUM_LIT:1> ] <EOL> if not os . path . exists ( pkg_file ) : <EOL> raise SPMPackageError ( '<STR_LIT>' . format ( pkg_file ) ) <EOL> formula_tar = tarfile . open ( pkg_file , '<STR_LIT>' ) <EOL> pkg_files = formula_tar . getmembers ( ) <EOL> for member in pkg_files : <EOL> self . ui . status ( member . name ) <EOL> def _list_files ( self , args ) : <EOL> '''<STR_LIT>''' <EOL> if len ( args ) < <NUM_LIT:2> : <EOL> raise SPMInvocationError ( '<STR_LIT>' ) <EOL> package = args [ <NUM_LIT:1> ] <EOL> files = self . _pkgdb_fun ( '<STR_LIT>' , package , self . db_conn ) <EOL> if files is None : <EOL> raise SPMPackageError ( '<STR_LIT>' . format ( package ) ) <EOL> else : <EOL> for file_ in files : <EOL> if self . opts [ '<STR_LIT>' ] : <EOL> status_msg = '<STR_LIT:U+002C>' . join ( file_ ) <EOL> else : <EOL> status_msg = file_ [ <NUM_LIT:0> ] <EOL> self . ui . status ( status_msg ) <EOL> def _build ( self , args ) : <EOL> '''<STR_LIT>''' <EOL> if len ( args ) < <NUM_LIT:2> : <EOL> raise SPMInvocationError ( '<STR_LIT>' ) <EOL> self . abspath = args [ <NUM_LIT:1> ] . rstrip ( '<STR_LIT:/>' ) <EOL> comps = self . abspath . split ( '<STR_LIT:/>' ) <EOL> self . relpath = comps [ - <NUM_LIT:1> ] <EOL> formula_path = '<STR_LIT>' . format ( self . abspath ) <EOL> if not os . path . exists ( formula_path ) : <EOL> raise SPMPackageError ( '<STR_LIT>' . format ( formula_path ) ) <EOL> with salt . utils . fopen ( formula_path ) as fp_ : <EOL> formula_conf = yaml . safe_load ( fp_ ) <EOL> for field in ( '<STR_LIT:name>' , '<STR_LIT:version>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:description>' ) : <EOL> if field not in formula_conf : <EOL> raise SPMPackageError ( '<STR_LIT>' . format ( field ) ) <EOL> out_path = '<STR_LIT>' . format ( <EOL> self . opts [ '<STR_LIT>' ] , <EOL> formula_conf [ '<STR_LIT:name>' ] , <EOL> formula_conf [ '<STR_LIT:version>' ] , <EOL> formula_conf [ '<STR_LIT>' ] , <EOL> ) <EOL> if not os . path . exists ( self . opts [ '<STR_LIT>' ] ) : <EOL> os . mkdir ( self . opts [ '<STR_LIT>' ] ) <EOL> self . formula_conf = formula_conf <EOL> formula_tar = tarfile . open ( out_path , '<STR_LIT>' ) <EOL> try : <EOL> formula_tar . add ( formula_path , formula_conf [ '<STR_LIT:name>' ] , filter = self . _exclude ) <EOL> formula_tar . add ( self . abspath , formula_conf [ '<STR_LIT:name>' ] , filter = self . _exclude ) <EOL> except TypeError : <EOL> formula_tar . add ( formula_path , formula_conf [ '<STR_LIT:name>' ] , exclude = self . _exclude ) <EOL> formula_tar . add ( self . abspath , formula_conf [ '<STR_LIT:name>' ] , exclude = self . _exclude ) <EOL> formula_tar . close ( ) <EOL> self . ui . status ( '<STR_LIT>' . format ( out_path ) ) <EOL> def _exclude ( self , member ) : <EOL> '''<STR_LIT>''' <EOL> if isinstance ( member , string_types ) : <EOL> return None <EOL> for item in self . opts [ '<STR_LIT>' ] : <EOL> if member . name . startswith ( '<STR_LIT>' . format ( self . formula_conf [ '<STR_LIT:name>' ] , item ) ) : <EOL> return None <EOL> elif member . name . startswith ( '<STR_LIT>' . format ( self . abspath , item ) ) : <EOL> return None <EOL> return member <EOL> class SPMUserInterface ( object ) : <EOL> '''<STR_LIT>''' <EOL> def status ( self , msg ) : <EOL> '''<STR_LIT>''' <EOL> raise NotImplementedError ( ) <EOL> def error ( self , msg ) : <EOL> '''<STR_LIT>''' <EOL> raise NotImplementedError ( ) <EOL> def confirm ( self , action ) : <EOL> '''<STR_LIT>''' <EOL> raise NotImplementedError ( ) <EOL> class SPMCmdlineInterface ( SPMUserInterface ) : <EOL> '''<STR_LIT>''' <EOL> def status ( self , msg ) : <EOL> print ( msg ) <EOL> def error ( self , msg ) : <EOL> print ( msg , file = sys . stderr ) <EOL> def confirm ( self , action ) : <EOL> print ( action ) <EOL> res = input ( '<STR_LIT>' ) <EOL> if not res . lower ( ) . startswith ( '<STR_LIT:y>' ) : <EOL> raise SPMOperationCanceled ( '<STR_LIT>' ) </s>
