<s> import codecs <EOL> import datetime <EOL> import fnmatch <EOL> import io <EOL> import inspect <EOL> import json <EOL> import logging <EOL> import os <EOL> import re <EOL> import subprocess <EOL> from jira . resources import Issue <EOL> import six <EOL> from six . moves . urllib import parse <EOL> from . import constants <EOL> from . import exceptions <EOL> from . import migrations <EOL> from . import utils <EOL> from . jiralinkmanager import JiraLinkManager <EOL> from . jirafieldmanager import JiraFieldManager <EOL> from . plugin import MacroPlugin , PluginValidationError <EOL> logger = logging . getLogger ( __name__ ) <EOL> class TicketFolder ( object ) : <EOL> def __init__ ( self , path , jira , migrate = True , quiet = False ) : <EOL> self . path = os . path . realpath ( <EOL> os . path . expanduser ( path ) <EOL> ) <EOL> self . quiet = quiet <EOL> self . issue_url = self . get_ticket_url ( ) <EOL> self . get_jira = jira <EOL> if not os . path . isdir ( self . metadata_dir ) : <EOL> raise exceptions . NotTicketFolderException ( <EOL> "<STR_LIT>" % ( <EOL> path <EOL> ) <EOL> ) <EOL> self . plugins = self . load_plugins ( ) <EOL> if migrate : <EOL> self . run_migrations ( ) <EOL> comment_path = self . get_local_path ( constants . TICKET_NEW_COMMENT ) <EOL> if not os . path . exists ( comment_path ) : <EOL> with io . open ( comment_path , '<STR_LIT:w>' , encoding = '<STR_LIT:utf-8>' ) as out : <EOL> out . write ( six . text_type ( '<STR_LIT>' ) ) <EOL> self . build_ignore_files ( ) <EOL> def __repr__ ( self ) : <EOL> if six . PY3 : <EOL> value = self . __unicode__ ( ) <EOL> else : <EOL> value = self . __str__ ( ) <EOL> return "<STR_LIT>" % value <EOL> def __unicode__ ( self ) : <EOL> return "<STR_LIT>" % ( self . ticket_number , self . path ) <EOL> def __str__ ( self ) : <EOL> if six . PY3 : <EOL> return self . __unicode__ ( ) <EOL> return self . __unicode__ ( ) . encode ( '<STR_LIT:utf8>' , '<STR_LIT:replace>' ) <EOL> @ property <EOL> def subtasks ( self ) : <EOL> if hasattr ( self , '<STR_LIT>' ) : <EOL> return self . _subtasks <EOL> self . _subtasks = [ ] <EOL> subtasks_path = self . get_metadata_path ( '<STR_LIT>' ) <EOL> if not os . path . exists ( subtasks_path ) : <EOL> return self . _subtasks <EOL> with open ( subtasks_path , '<STR_LIT:r>' ) as in_ : <EOL> for line in in_ : <EOL> ticket_number = line . strip ( ) <EOL> folder = self . __class__ ( <EOL> self . get_path ( <EOL> ticket_number , <EOL> ) , <EOL> utils . lazy_get_jira ( ) <EOL> ) <EOL> self . _subtasks . append ( folder ) <EOL> return self . _subtasks <EOL> def execute_plugin_method_series ( <EOL> self , name , args = None , kwargs = None , single_response = False <EOL> ) : <EOL> if args is None : <EOL> args = [ ] <EOL> use_kwargs = True <EOL> if kwargs is None : <EOL> kwargs = { } <EOL> use_kwargs = False <EOL> if use_kwargs and single_response : <EOL> raise RuntimeError ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> ) <EOL> elif args and kwargs : <EOL> raise RuntimeError ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> ) <EOL> for plugin in self . plugins : <EOL> if not hasattr ( plugin , name ) : <EOL> continue <EOL> method = getattr ( plugin , name ) <EOL> plugin_result = method ( * args , ** kwargs ) <EOL> if plugin_result is not None : <EOL> if use_kwargs : <EOL> kwargs = plugin_result <EOL> elif single_response : <EOL> args = ( plugin_result , ) <EOL> else : <EOL> args = plugin_result <EOL> if use_kwargs : <EOL> return kwargs <EOL> elif single_response : <EOL> return args [ <NUM_LIT:0> ] <EOL> return args <EOL> def load_plugins ( self ) : <EOL> config = self . get_config ( ) <EOL> plugins = [ ] <EOL> if not config . has_section ( constants . CONFIG_PLUGINS ) : <EOL> return plugins <EOL> installed_plugins = utils . get_installed_plugins ( ) <EOL> for name , status in config . items ( constants . CONFIG_PLUGINS ) : <EOL> if not utils . convert_to_boolean ( status ) : <EOL> continue <EOL> if name not in installed_plugins : <EOL> self . log ( <EOL> "<STR_LIT>" , <EOL> ( name , ) , <EOL> ) <EOL> continue <EOL> plugin = installed_plugins [ name ] ( self , name ) <EOL> try : <EOL> plugin . validate ( ) <EOL> except PluginValidationError as e : <EOL> self . log ( <EOL> "<STR_LIT>" , <EOL> ( name , e , ) <EOL> ) <EOL> plugins . append ( plugin ) <EOL> return plugins <EOL> def get_config ( self ) : <EOL> local_config_file = self . get_metadata_path ( '<STR_LIT>' ) <EOL> additional_configs = [ ] <EOL> if os . path . exists ( local_config_file ) : <EOL> additional_configs . append ( <EOL> local_config_file <EOL> ) <EOL> return utils . get_config ( additional_configs ) <EOL> def set_config_value ( self , section , key , value ) : <EOL> with utils . stash_local_changes ( self ) : <EOL> local_config_file = self . get_metadata_path ( '<STR_LIT>' ) <EOL> config = utils . get_config ( <EOL> additional_configs = [ <EOL> local_config_file , <EOL> ] , <EOL> include_global = False , <EOL> ) <EOL> if not config . has_section ( section ) : <EOL> config . add_section ( section ) <EOL> config . set ( section , key , value ) <EOL> with open ( local_config_file , '<STR_LIT:w>' ) as out : <EOL> config . write ( out ) <EOL> self . run_git_command ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> self . run_git_command ( <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> failure_ok = True <EOL> ) <EOL> @ property <EOL> def jira_base ( self ) : <EOL> match = re . match ( '<STR_LIT>' , self . issue_url ) <EOL> if not match : <EOL> raise ValueError ( <EOL> "<STR_LIT>" % ( <EOL> self . issue_url , <EOL> ) <EOL> ) <EOL> return match . group ( <NUM_LIT:1> ) <EOL> @ property <EOL> def ticket_number ( self ) : <EOL> parts = parse . urlparse ( self . issue_url ) <EOL> match = re . match ( '<STR_LIT>' , parts . path ) <EOL> if not match : <EOL> raise ValueError ( <EOL> "<STR_LIT>" % self . issue_url <EOL> ) <EOL> return match . group ( <NUM_LIT:1> ) <EOL> @ property <EOL> def jira ( self ) : <EOL> if not hasattr ( self , '<STR_LIT>' ) : <EOL> self . _jira = self . get_jira ( <EOL> self . jira_base , <EOL> config = self . get_config ( ) <EOL> ) <EOL> return self . _jira <EOL> @ property <EOL> def issue ( self ) : <EOL> if not hasattr ( self , '<STR_LIT>' ) : <EOL> self . _issue = self . jira . issue ( self . ticket_number ) <EOL> return self . _issue <EOL> def clear_cache ( self ) : <EOL> if hasattr ( self , '<STR_LIT>' ) : <EOL> del self . _issue <EOL> if hasattr ( self , '<STR_LIT>' ) : <EOL> del self . _jira <EOL> def store_cached_issue ( self , shadow = True ) : <EOL> storable = { <EOL> '<STR_LIT>' : self . issue . _options , <EOL> '<STR_LIT>' : self . issue . raw <EOL> } <EOL> with io . open ( <EOL> self . get_path ( '<STR_LIT>' , shadow = shadow ) , <EOL> '<STR_LIT:w>' , <EOL> encoding = '<STR_LIT:utf-8>' , <EOL> ) as out : <EOL> out . write ( <EOL> six . text_type ( <EOL> json . dumps ( <EOL> storable , <EOL> indent = <NUM_LIT:4> , <EOL> sort_keys = True , <EOL> ensure_ascii = False , <EOL> ) <EOL> ) <EOL> ) <EOL> @ property <EOL> def cached_issue ( self ) : <EOL> if not hasattr ( self , '<STR_LIT>' ) : <EOL> try : <EOL> issue_path = self . get_metadata_path ( '<STR_LIT>' ) <EOL> with io . open ( issue_path , '<STR_LIT:r>' , encoding = '<STR_LIT:utf-8>' ) as _in : <EOL> storable = json . loads ( _in . read ( ) ) <EOL> self . _cached_issue = Issue ( <EOL> storable [ '<STR_LIT>' ] , <EOL> None , <EOL> storable [ '<STR_LIT>' ] , <EOL> ) <EOL> except IOError : <EOL> self . log ( <EOL> '<STR_LIT>' , <EOL> level = logging . ERROR , <EOL> ) <EOL> self . _cached_issue = self . issue <EOL> return self . _cached_issue <EOL> @ property <EOL> def metadata_dir ( self ) : <EOL> return os . path . join ( <EOL> self . path , <EOL> constants . METADATA_DIR , <EOL> ) <EOL> @ property <EOL> def git_merge_base ( self ) : <EOL> return self . run_git_command ( <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> ) <EOL> def get_ticket_url ( self ) : <EOL> try : <EOL> with io . open ( <EOL> self . get_metadata_path ( '<STR_LIT>' ) , <EOL> '<STR_LIT:r>' , <EOL> encoding = '<STR_LIT:utf-8>' <EOL> ) as in_ : <EOL> return in_ . read ( ) . strip ( ) <EOL> except ( IOError , OSError ) : <EOL> return None <EOL> def get_metadata_path ( self , * args ) : <EOL> return os . path . join ( <EOL> self . metadata_dir , <EOL> * args <EOL> ) <EOL> def get_remote_file_metadata ( self , shadow = True ) : <EOL> remote_files = self . get_path ( <EOL> '<STR_LIT>' , <EOL> shadow = shadow <EOL> ) <EOL> try : <EOL> with io . open ( remote_files , '<STR_LIT:r>' , encoding = '<STR_LIT:utf-8>' ) as _in : <EOL> data = json . loads ( _in . read ( ) ) <EOL> except IOError : <EOL> data = { } <EOL> return self . execute_plugin_method_series ( <EOL> '<STR_LIT>' , <EOL> args = ( data , ) , <EOL> single_response = True , <EOL> ) <EOL> def set_remote_file_metadata ( self , data , shadow = True ) : <EOL> data = self . execute_plugin_method_series ( <EOL> '<STR_LIT>' , <EOL> args = ( data , ) , <EOL> single_response = True , <EOL> ) <EOL> remote_files = self . get_path ( <EOL> '<STR_LIT>' , <EOL> shadow = shadow <EOL> ) <EOL> with io . open ( remote_files , '<STR_LIT:w>' , encoding = '<STR_LIT:utf-8>' ) as out : <EOL> out . write ( <EOL> six . text_type ( <EOL> json . dumps ( <EOL> data , <EOL> indent = <NUM_LIT:4> , <EOL> sort_keys = True , <EOL> ensure_ascii = False , <EOL> ) <EOL> ) <EOL> ) <EOL> def get_local_path ( self , * args ) : <EOL> return os . path . join ( <EOL> self . path , <EOL> * args <EOL> ) <EOL> def get_shadow_path ( self , * args ) : <EOL> return os . path . join ( <EOL> self . get_metadata_path ( '<STR_LIT>' ) , <EOL> * args <EOL> ) <EOL> def get_path ( self , * args , ** kwargs ) : <EOL> shadow = kwargs . get ( '<STR_LIT>' , False ) <EOL> if shadow : <EOL> return self . get_shadow_path ( * args ) <EOL> return self . get_local_path ( * args ) <EOL> @ property <EOL> def version ( self ) : <EOL> try : <EOL> with io . open ( <EOL> self . get_metadata_path ( '<STR_LIT:version>' ) , <EOL> '<STR_LIT:r>' , <EOL> encoding = '<STR_LIT:utf-8>' <EOL> ) as _in : <EOL> return int ( _in . read ( ) . strip ( ) ) <EOL> except IOError : <EOL> return <NUM_LIT:1> <EOL> @ property <EOL> def log_path ( self ) : <EOL> return self . get_metadata_path ( constants . TICKET_OPERATION_LOG ) <EOL> @ classmethod <EOL> def initialize_ticket_folder ( cls , ticket_url , path , jira ) : <EOL> path = os . path . realpath ( path ) <EOL> metadata_path = os . path . join ( <EOL> path , <EOL> constants . METADATA_DIR , <EOL> ) <EOL> os . mkdir ( metadata_path ) <EOL> with io . open ( <EOL> os . path . join ( metadata_path , '<STR_LIT>' ) , <EOL> '<STR_LIT:w>' , <EOL> encoding = '<STR_LIT:utf-8>' <EOL> ) as out : <EOL> out . write ( six . text_type ( ticket_url ) ) <EOL> subprocess . check_call ( <EOL> ( <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> os . path . join ( <EOL> metadata_path , <EOL> '<STR_LIT>' , <EOL> ) <EOL> ) , <EOL> stdout = subprocess . PIPE <EOL> ) <EOL> subprocess . check_call ( ( <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' % os . path . join ( <EOL> metadata_path , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' <EOL> ) , <EOL> '<STR_LIT>' , <EOL> constants . GIT_IGNORE_FILE , <EOL> ) ) <EOL> excludes_path = os . path . join ( metadata_path , '<STR_LIT>' , '<STR_LIT:info>' , '<STR_LIT>' ) <EOL> with io . open ( excludes_path , '<STR_LIT:w>' , encoding = '<STR_LIT:utf-8>' ) as gitignore : <EOL> gitignore . write ( <EOL> six . text_type ( '<STR_LIT:\n>' ) . join ( <EOL> [ <EOL> '<STR_LIT>' % constants . METADATA_DIR , <EOL> '<STR_LIT>' % constants . METADATA_DIR , <EOL> '<STR_LIT>' % constants . METADATA_DIR , <EOL> ] <EOL> ) <EOL> ) <EOL> instance = cls ( path , jira , migrate = False ) <EOL> instance . log ( <EOL> '<STR_LIT>' , <EOL> ( instance . ticket_number , instance . path , ) <EOL> ) <EOL> instance . run_git_command ( <EOL> '<STR_LIT>' , '<STR_LIT>' <EOL> ) <EOL> instance . run_git_command ( <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' <EOL> ) <EOL> instance . run_migrations ( init = True ) <EOL> comment_path = instance . get_local_path ( constants . TICKET_NEW_COMMENT ) <EOL> with io . open ( comment_path , '<STR_LIT:w>' , encoding = '<STR_LIT:utf-8>' ) as out : <EOL> out . write ( six . text_type ( '<STR_LIT>' ) ) <EOL> return instance <EOL> def applied_macros_exist ( self , shadow = False ) : <EOL> macro_patch_filename = self . get_path ( <EOL> '<STR_LIT>' , <EOL> shadow = shadow , <EOL> ) <EOL> if not os . path . exists ( macro_patch_filename ) : <EOL> return False <EOL> with open ( macro_patch_filename ) as incoming : <EOL> if incoming . read ( ) . strip ( ) : <EOL> return True <EOL> return False <EOL> def run_git_command ( self , command , * args , ** kwargs ) : <EOL> failure_ok = kwargs . get ( '<STR_LIT>' , False ) <EOL> shadow = kwargs . get ( '<STR_LIT>' , False ) <EOL> binary = kwargs . get ( '<STR_LIT>' , False ) <EOL> stdin = kwargs . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> args = list ( args ) <EOL> if not shadow : <EOL> work_tree = self . path , <EOL> git_dir = self . get_metadata_path ( '<STR_LIT>' ) <EOL> cwd = self . path <EOL> else : <EOL> work_tree = self . get_metadata_path ( '<STR_LIT>' ) <EOL> git_dir = self . get_metadata_path ( '<STR_LIT>' ) <EOL> cwd = self . get_metadata_path ( '<STR_LIT>' ) <EOL> cmd = [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' % work_tree , <EOL> '<STR_LIT>' % git_dir , <EOL> ] <EOL> cmd . append ( command ) <EOL> if command == '<STR_LIT>' : <EOL> args . append ( <EOL> "<STR_LIT>" % constants . GIT_AUTHOR <EOL> ) <EOL> cmd . extend ( args ) <EOL> self . log ( <EOL> '<STR_LIT>' , <EOL> ( <EOL> "<STR_LIT:U+0020>" . join ( cmd ) , <EOL> ) , <EOL> logging . DEBUG , <EOL> sublogger = '<STR_LIT>' , <EOL> ) <EOL> handle = subprocess . Popen ( <EOL> cmd , <EOL> cwd = cwd , <EOL> stdin = subprocess . PIPE , <EOL> stderr = subprocess . STDOUT , <EOL> stdout = subprocess . PIPE <EOL> ) <EOL> result , _ = handle . communicate ( stdin ) <EOL> if handle . returncode != <NUM_LIT:0> and not failure_ok : <EOL> command = '<STR_LIT:U+0020>' . join ( cmd ) <EOL> raise exceptions . GitCommandError ( <EOL> "<STR_LIT>" % command , <EOL> returncode = handle . returncode , <EOL> stdout = result , <EOL> cmd = command <EOL> ) <EOL> if not binary : <EOL> return result . decode ( '<STR_LIT:utf-8>' ) . strip ( ) <EOL> return result <EOL> def get_local_file_at_revision ( <EOL> self , path , revision , failure_ok = True , binary = False <EOL> ) : <EOL> return self . run_git_command ( <EOL> '<STR_LIT>' , '<STR_LIT>' % ( <EOL> revision , <EOL> path , <EOL> ) , <EOL> failure_ok = failure_ok , <EOL> binary = binary , <EOL> ) <EOL> def get_ignore_globs ( self , which = constants . LOCAL_ONLY_FILE ) : <EOL> all_globs = [ <EOL> constants . TICKET_DETAILS , <EOL> constants . TICKET_COMMENTS , <EOL> constants . TICKET_NEW_COMMENT , <EOL> constants . TICKET_LINKS , <EOL> ] <EOL> for field in constants . FILE_FIELDS : <EOL> all_globs . append ( <EOL> constants . TICKET_FILE_FIELD_TEMPLATE . format ( field_name = field ) <EOL> ) <EOL> for plugin in self . plugins : <EOL> if hasattr ( plugin , '<STR_LIT>' ) : <EOL> all_globs . extend ( plugin . get_ignore_globs ( ) ) <EOL> def get_globs_from_file ( input_file ) : <EOL> globs = [ ] <EOL> for line in input_file . readlines ( ) : <EOL> if line . startswith ( '<STR_LIT:#>' ) or not line . strip ( ) : <EOL> continue <EOL> globs . append ( line . strip ( ) ) <EOL> return globs <EOL> try : <EOL> with io . open ( <EOL> self . get_local_path ( which ) , <EOL> '<STR_LIT:r>' , <EOL> encoding = '<STR_LIT:utf-8>' <EOL> ) as local_ign : <EOL> all_globs . extend ( <EOL> get_globs_from_file ( local_ign ) <EOL> ) <EOL> except IOError : <EOL> pass <EOL> try : <EOL> with io . open ( <EOL> os . path . expanduser ( '<STR_LIT>' % which ) , <EOL> '<STR_LIT:r>' , <EOL> encoding = '<STR_LIT:utf-8>' <EOL> ) as global_ignores : <EOL> all_globs . extend ( <EOL> get_globs_from_file ( global_ignores ) <EOL> ) <EOL> except IOError : <EOL> pass <EOL> return all_globs <EOL> def file_matches_globs ( self , filename , ignore_globs ) : <EOL> for glob in ignore_globs : <EOL> if fnmatch . fnmatch ( filename , glob ) : <EOL> return True <EOL> return False <EOL> def get_ready_changes ( self ) : <EOL> ready = { <EOL> '<STR_LIT>' : ( <EOL> self . get_fields ( '<STR_LIT>' ) - self . get_fields ( self . git_merge_base ) <EOL> ) , <EOL> '<STR_LIT>' : ( <EOL> self . get_links ( '<STR_LIT>' ) - self . get_links ( self . git_merge_base ) <EOL> ) , <EOL> '<STR_LIT>' : self . get_new_comment ( ready = True ) , <EOL> } <EOL> changed_files = self . filter_ignored_files ( <EOL> self . run_git_command ( <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' % self . git_merge_base , <EOL> ) . split ( '<STR_LIT:\n>' ) , <EOL> constants . LOCAL_ONLY_FILE <EOL> ) <EOL> ready [ '<STR_LIT>' ] = changed_files <EOL> return ready <EOL> def get_uncommitted_changes ( self ) : <EOL> uncommitted = { <EOL> '<STR_LIT>' : self . get_fields ( ) - self . get_fields ( '<STR_LIT>' ) , <EOL> '<STR_LIT>' : self . get_new_comment ( ready = False ) , <EOL> '<STR_LIT>' : self . get_links ( ) - self . get_links ( '<STR_LIT>' ) , <EOL> } <EOL> new_files = self . run_git_command ( <EOL> '<STR_LIT>' , '<STR_LIT>' , failure_ok = True <EOL> ) . split ( '<STR_LIT:\n>' ) <EOL> modified_files = self . run_git_command ( <EOL> '<STR_LIT>' , '<STR_LIT>' , failure_ok = True <EOL> ) . split ( '<STR_LIT:\n>' ) <EOL> uncommitted [ '<STR_LIT>' ] = self . filter_ignored_files ( <EOL> [ <EOL> filename for filename in new_files + modified_files <EOL> if filename <EOL> ] , <EOL> constants . LOCAL_ONLY_FILE , <EOL> constants . GIT_IGNORE_FILE , <EOL> constants . GIT_EXCLUDE_FILE , <EOL> ) <EOL> return uncommitted <EOL> def get_local_uncommitted_changes ( self ) : <EOL> new_files = self . run_git_command ( <EOL> '<STR_LIT>' , '<STR_LIT>' , failure_ok = True <EOL> ) . split ( '<STR_LIT:\n>' ) <EOL> modified_files = self . run_git_command ( <EOL> '<STR_LIT>' , '<STR_LIT>' , failure_ok = True <EOL> ) . split ( '<STR_LIT:\n>' ) <EOL> committable = self . filter_ignored_files ( <EOL> [ <EOL> filename for filename in new_files + modified_files if filename <EOL> ] , <EOL> constants . LOCAL_ONLY_FILE <EOL> ) <EOL> uncommitted = self . filter_ignored_files ( <EOL> [ <EOL> filename for filename in modified_files + new_files <EOL> if filename not in committable <EOL> ] , <EOL> constants . GIT_IGNORE_FILE , <EOL> constants . GIT_EXCLUDE_FILE , <EOL> ) <EOL> return { <EOL> '<STR_LIT>' : uncommitted <EOL> } <EOL> def get_remotely_changed ( self ) : <EOL> metadata = self . get_remote_file_metadata ( shadow = True ) <EOL> assets = [ ] <EOL> attachments = self . filter_ignored_files ( <EOL> getattr ( self . issue . fields , '<STR_LIT>' , [ ] ) , <EOL> constants . REMOTE_IGNORE_FILE <EOL> ) <EOL> for attachment in attachments : <EOL> changed = metadata . get ( attachment . filename ) != attachment . created <EOL> if changed : <EOL> assets . append ( attachment . filename ) <EOL> return self . execute_plugin_method_series ( <EOL> name = '<STR_LIT>' , <EOL> args = ( assets , ) , <EOL> single_response = True , <EOL> ) <EOL> def filter_ignored_files ( self , files , * which ) : <EOL> if len ( which ) < <NUM_LIT:1> : <EOL> which = [ constants . LOCAL_ONLY_FILE ] <EOL> if not isinstance ( which , ( list , tuple ) ) : <EOL> which = [ which ] <EOL> for list_path in which : <EOL> ignore_globs = self . get_ignore_globs ( list_path ) <EOL> assets = [ ] <EOL> for fileish in files : <EOL> filename = fileish <EOL> attachment = False <EOL> if not isinstance ( fileish , six . string_types ) : <EOL> filename = fileish . filename <EOL> attachment = True <EOL> if self . file_matches_globs ( filename , ignore_globs ) : <EOL> continue <EOL> if ( <EOL> not attachment and <EOL> not os . path . isfile ( os . path . join ( self . path , filename ) ) <EOL> ) : <EOL> continue <EOL> if filename . startswith ( '<STR_LIT:.>' ) : <EOL> continue <EOL> assets . append ( fileish ) <EOL> files = assets <EOL> return self . execute_plugin_method_series ( <EOL> name = '<STR_LIT>' , <EOL> args = ( assets , ) , <EOL> single_response = True , <EOL> ) <EOL> def get_macro_plugins ( self ) : <EOL> if not hasattr ( self , '<STR_LIT>' ) : <EOL> config = self . get_config ( ) <EOL> plugins = [ ] <EOL> if not config . has_section ( constants . CONFIG_PLUGINS ) : <EOL> return plugins <EOL> installed_plugins = utils . get_installed_plugins ( MacroPlugin ) <EOL> for name , status in config . items ( constants . CONFIG_PLUGINS ) : <EOL> if not utils . convert_to_boolean ( status ) : <EOL> continue <EOL> if name not in installed_plugins : <EOL> self . log ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" , <EOL> ( name , ) , <EOL> level = logging . DEBUG <EOL> ) <EOL> continue <EOL> plugin = installed_plugins [ name ] ( self , name ) <EOL> try : <EOL> plugin . validate ( ) <EOL> except PluginValidationError as e : <EOL> self . log ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" , <EOL> ( name , e , ) , <EOL> ) <EOL> plugins . append ( plugin ) <EOL> self . _macro_plugins = plugins <EOL> return self . _macro_plugins <EOL> def process_plugin_builds ( self ) : <EOL> results = { } <EOL> for plugin in self . plugins : <EOL> if hasattr ( plugin , '<STR_LIT>' ) : <EOL> results [ plugin . plugin_name ] = plugin . run_build_process ( ) <EOL> return results <EOL> def process_macros ( self , data ) : <EOL> macro_plugins = self . get_macro_plugins ( ) <EOL> for cls in macro_plugins : <EOL> if isinstance ( data , six . string_types ) : <EOL> data = cls . process_text_data ( data ) <EOL> else : <EOL> continue <EOL> return data <EOL> def get_links ( self , revision = None , path = None ) : <EOL> kwargs = { } <EOL> if not revision : <EOL> kwargs [ '<STR_LIT:path>' ] = path if path else self . path <EOL> else : <EOL> kwargs [ '<STR_LIT>' ] = revision <EOL> return JiraLinkManager . create ( <EOL> self , <EOL> ** kwargs <EOL> ) <EOL> def get_fields ( self , revision = None , path = None ) : <EOL> kwargs = { } <EOL> if not revision : <EOL> kwargs [ '<STR_LIT:path>' ] = path if path else self . path <EOL> else : <EOL> kwargs [ '<STR_LIT>' ] = revision <EOL> return JiraFieldManager . create ( <EOL> self , <EOL> ** kwargs <EOL> ) <EOL> def get_new_comment ( self , clear = False , staged = False , ready = True ) : <EOL> try : <EOL> with io . open ( <EOL> self . get_local_path ( constants . TICKET_NEW_COMMENT ) , <EOL> '<STR_LIT>' , <EOL> encoding = '<STR_LIT:utf-8>' , <EOL> ) as c : <EOL> local_contents = c . read ( ) . strip ( ) <EOL> if ready : <EOL> contents = self . get_local_file_at_revision ( <EOL> constants . TICKET_NEW_COMMENT , <EOL> '<STR_LIT>' <EOL> ) <EOL> if contents : <EOL> contents = contents . strip ( ) <EOL> else : <EOL> contents = '<STR_LIT>' <EOL> else : <EOL> contents = local_contents <EOL> if not ready and contents == self . get_new_comment ( ready = True ) : <EOL> contents = '<STR_LIT>' <EOL> if contents == local_contents and clear : <EOL> with io . open ( <EOL> self . get_local_path ( constants . TICKET_NEW_COMMENT ) , <EOL> '<STR_LIT>' , <EOL> encoding = '<STR_LIT:utf-8>' , <EOL> ) as c : <EOL> c . truncate ( ) <EOL> except IOError : <EOL> contents = '<STR_LIT>' <EOL> contents = self . process_macros ( contents ) <EOL> return self . execute_plugin_method_series ( <EOL> name = '<STR_LIT>' , <EOL> args = ( contents , ) , <EOL> single_response = True , <EOL> ) <EOL> def is_up_to_date ( self ) : <EOL> jira_commit = self . run_git_command ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> master_commit = self . run_git_command ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> try : <EOL> self . run_git_command ( <EOL> '<STR_LIT>' , '<STR_LIT>' , jira_commit , master_commit , <EOL> ) <EOL> except exceptions . GitCommandError : <EOL> return False <EOL> return True <EOL> def status ( self ) : <EOL> status = { <EOL> '<STR_LIT>' : self . get_ready_changes ( ) , <EOL> '<STR_LIT>' : self . get_local_uncommitted_changes ( ) , <EOL> '<STR_LIT>' : self . get_uncommitted_changes ( ) , <EOL> '<STR_LIT>' : self . is_up_to_date ( ) , <EOL> } <EOL> return self . execute_plugin_method_series ( <EOL> '<STR_LIT>' , <EOL> args = ( status , ) , <EOL> single_response = True , <EOL> ) <EOL> return status <EOL> def run_migrations ( self , init = False ) : <EOL> loglevel = logging . INFO <EOL> if init : <EOL> loglevel = logging . DEBUG <EOL> else : <EOL> if not os . path . exists ( self . get_metadata_path ( '<STR_LIT>' ) ) : <EOL> raise exceptions . JirafsError ( <EOL> u"<STR_LIT>" . format ( <EOL> path = self . path <EOL> ) <EOL> ) <EOL> if self . version < constants . CURRENT_REPO_VERSION : <EOL> print ( <EOL> u"<STR_LIT>" <EOL> u"<STR_LIT>" . format ( <EOL> path = self . path <EOL> ) <EOL> ) <EOL> while self . version < constants . CURRENT_REPO_VERSION : <EOL> migrator = getattr ( <EOL> migrations , <EOL> '<STR_LIT>' % str ( self . version + <NUM_LIT:1> ) . zfill ( <NUM_LIT:4> ) <EOL> ) <EOL> self . migrate ( migrator , loglevel = loglevel , init = init ) <EOL> def migrate ( self , migrator , loglevel = logging . INFO , init = False ) : <EOL> with utils . stash_local_changes ( self ) : <EOL> self . log ( '<STR_LIT>' , ( migrator . __name__ , ) , loglevel ) <EOL> migrator ( self , init = init ) <EOL> self . log ( '<STR_LIT>' , ( migrator . __name__ , ) , loglevel ) <EOL> def build_ignore_files ( self ) : <EOL> metadata_excludes = [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> ] <EOL> with codecs . open ( <EOL> self . get_local_path ( constants . GIT_EXCLUDE_FILE ) , <EOL> '<STR_LIT:w>' , <EOL> '<STR_LIT:utf-8>' <EOL> ) as out : <EOL> for line in metadata_excludes : <EOL> out . write ( <EOL> '<STR_LIT>' % ( <EOL> constants . METADATA_DIR , <EOL> line , <EOL> ) <EOL> ) <EOL> subtask_list_path = self . get_metadata_path ( '<STR_LIT>' ) <EOL> if os . path . exists ( subtask_list_path ) : <EOL> with open ( subtask_list_path , '<STR_LIT:r>' ) as in_ : <EOL> for line in in_ : <EOL> out . write ( <EOL> '<STR_LIT>' % line . strip ( ) <EOL> ) <EOL> with codecs . open ( <EOL> self . get_metadata_path ( '<STR_LIT>' ) , <EOL> '<STR_LIT:w>' , <EOL> '<STR_LIT:utf-8>' <EOL> ) as out : <EOL> try : <EOL> out . write ( '<STR_LIT>' % constants . GIT_IGNORE_FILE_PARTIAL ) <EOL> with codecs . open ( <EOL> os . path . expanduser ( <EOL> '<STR_LIT>' % constants . GIT_IGNORE_FILE_PARTIAL <EOL> ) , <EOL> '<STR_LIT:r>' , <EOL> '<STR_LIT:utf-8>' <EOL> ) as in_ : <EOL> for line in in_ : <EOL> out . write ( <EOL> '<STR_LIT>' % line . strip ( ) <EOL> ) <EOL> except : <EOL> pass <EOL> try : <EOL> out . write ( <EOL> '<STR_LIT>' % ( <EOL> self . get_path ( constants . GIT_IGNORE_FILE_PARTIAL ) <EOL> ) <EOL> ) <EOL> with codecs . open ( <EOL> self . get_path ( constants . GIT_IGNORE_FILE_PARTIAL ) , <EOL> '<STR_LIT:r>' , <EOL> '<STR_LIT:utf-8>' <EOL> ) as in_ : <EOL> for line in in_ : <EOL> out . write ( '<STR_LIT>' % line . strip ( ) ) <EOL> except : <EOL> pass <EOL> def log ( self , message , args = None , level = logging . INFO , sublogger = None ) : <EOL> if args is None : <EOL> args = [ ] <EOL> module_name = inspect . getmodule ( inspect . stack ( ) [ <NUM_LIT:1> ] [ <NUM_LIT:0> ] ) . __name__ <EOL> logger_name = module_name <EOL> if sublogger : <EOL> logger_name = '<STR_LIT>' . format ( <EOL> module_name = module_name , <EOL> sublogger = sublogger <EOL> ) <EOL> logger . log ( level , message , * args ) <EOL> with io . open ( self . log_path , '<STR_LIT:a>' , encoding = '<STR_LIT:utf-8>' ) as log_file : <EOL> log_file . write ( <EOL> six . text_type ( <EOL> u"<STR_LIT>" . format ( <EOL> date = datetime . datetime . utcnow ( ) . isoformat ( ) , <EOL> level = logging . getLevelName ( level ) , <EOL> module = logger_name , <EOL> message = ( message % args ) . replace ( '<STR_LIT:\n>' , '<STR_LIT>' ) <EOL> ) <EOL> ) <EOL> ) <EOL> if level >= logging . INFO and not self . quiet : <EOL> print ( <EOL> u"<STR_LIT>" % ( <EOL> logging . getLevelName ( level ) , <EOL> self . issue , <EOL> message % args <EOL> ) <EOL> ) <EOL> def get_log ( self ) : <EOL> with io . open ( self . log_path , '<STR_LIT:r>' , encoding = '<STR_LIT:utf-8>' ) as log_file : <EOL> return log_file . read ( ) </s>
