def test_bear_dirs(self): section = Section('section', None) empty_bear_dirs_len = len(section.bear_dirs()) section.append(Setting('bear_dirs', 'test1, test2 (1)')) self.assertEqual(len(section.bear_dirs()), empty_bear_dirs_len + 2) # Verify if bear directories are properly escaped root = get_config_directory(section) path = os.path.join(glob_escape(root), glob_escape('test2 (1)'), '**') self.assertIn(path, section.bear_dirs())
def test_bear_dirs(self): section = Section("section", None) empty_bear_dirs_len = len(section.bear_dirs()) section.append(Setting("bear_dirs", "test1, test2 (1)")) self.assertEqual(len(section.bear_dirs()), empty_bear_dirs_len + 2) # Verify if bear directories are properly escaped root = get_config_directory(section) path = os.path.join(glob_escape(root), glob_escape("test2 (1)"), "**") self.assertIn(path, section.bear_dirs())
def test_glob_list(self): abspath = glob_escape(os.path.abspath(".")) # Need to escape backslashes since we use list conversion self.uut = Setting("key", "., " + abspath.replace("\\", "\\\\"), origin=os.path.join("test (1)", "somefile")) self.assertEqual( glob_list(self.uut), [glob_escape(os.path.abspath(os.path.join("test (1)", "."))), abspath])
def test_glob_list(self): abspath = glob_escape(os.path.abspath('.')) # Need to escape backslashes since we use list conversion self.uut = Setting('key', '., ' + abspath.replace('\\', '\\\\'), origin=os.path.join('test (1)', 'somefile')) self.assertEqual( glob_list(self.uut), [glob_escape(os.path.abspath(os.path.join('test (1)', '.'))), abspath])
def test_glob_list(self): abspath = glob_escape(os.path.abspath(".")) # Need to escape backslashes since we use list conversion self.uut = Setting("key", "., " + abspath.replace("\\", "\\\\"), origin=os.path.join("test (1)", "somefile")) self.assertEqual(glob_list(self.uut), [ glob_escape(os.path.abspath(os.path.join("test (1)", "."))), abspath ])
def test_glob(self): self.uut = Setting('key', '.', origin=os.path.join('test (1)', 'somefile')) self.assertEqual(glob(self.uut), glob_escape(os.path.abspath('test (1)'))) self.uut = Setting('key', '.', origin=SourcePosition( os.path.join('test (1)', 'somefile'))) self.assertEqual(glob(self.uut), glob_escape(os.path.abspath('test (1)')))
def bear_dirs(self): bear_dirs = path_list(self.get("bear_dirs", "")) for bear_dir in bear_dirs: sys.path.append(bear_dir) bear_dir_globs = [ os.path.join(glob_escape(bear_dir), "**") for bear_dir in bear_dirs] bear_dir_globs += [ os.path.join(glob_escape(bear_dir), "**") for bear_dir in collect_registered_bears_dirs('coalabears')] return bear_dir_globs
def bear_dirs(self): bear_dirs = path_list(self.get('bear_dirs', '')) for bear_dir in bear_dirs: sys.path.append(bear_dir) bear_dir_globs = [ os.path.join(glob_escape(bear_dir), '**') for bear_dir in bear_dirs] bear_dir_globs += [ os.path.join(glob_escape(bear_dir), '**') for bear_dir in collect_registered_bears_dirs('coalabears')] return bear_dir_globs
def main(log_printer=None, section: Section=None): start_path = get_config_directory(section) log_printer = log_printer or LogPrinter(ConsolePrinter()) if start_path is None: return 255 # start_path may have unintended glob characters orig_files = Globbing.glob(os.path.join( glob_escape(start_path), '**', '*.orig')) not_deleted = 0 for ofile in orig_files: log_printer.info("Deleting old backup file... " + os.path.relpath(ofile)) try: os.remove(ofile) except OSError as oserror: not_deleted += 1 log_printer.warn("Couldn't delete {}. {}".format( os.path.relpath(ofile), oserror.strerror)) if not_deleted: log_printer.warn(str(not_deleted) + " .orig backup files could not be" " deleted, possibly because you lack the permission" " to do so. coala may not be able to create" " backup files when patches are applied.") return 0
def test_glob_escape(self): input_strings = [ "test", "test[", "test []", "test [[]", "test ]] str [", "test[][]", "test(", "test)", "test()", "test (1)"] output_strings = [ "test", "test[[]", "test [[][]]", "test [[][[][]]", "test []][]] str [[]", "test[[][]][[][]]", "test[(]", "test[)]", "test[(][)]", "test [(]1[)]"] for unescaped_str, escaped_str in zip(input_strings, output_strings): self.assertEqual(glob_escape(unescaped_str), escaped_str)
def test_glob_escape(self): input_strings = [ 'test', 'test[', 'test []', 'test [[]', 'test ]] str [', 'test[][]', 'test(', 'test)', 'test()', 'test (1)'] output_strings = [ 'test', 'test[[]', 'test [[][]]', 'test [[][[][]]', 'test []][]] str [[]', 'test[[][]][[][]]', 'test[(]', 'test[)]', 'test[(][)]', 'test [(]1[)]'] for unescaped_str, escaped_str in zip(input_strings, output_strings): self.assertEqual(glob_escape(unescaped_str), escaped_str)
def get_project_files(log_printer, printer, project_dir, file_path_completer, non_interactive=False): """ Gets the list of files matching files in the user's project directory after prompting for glob expressions. :param log_printer: A ``LogPrinter`` object. :param printer: A ``ConsolePrinter`` object. :param file_path_completer: A ``file_path_completer`` object. :param non_interactive Whether coala-quickstart is in non-interactive mode :return: A list of file paths matching the files. """ file_globs = ['**'] ignore_globs = None if os.path.isfile(os.path.join(project_dir, '.gitignore')): printer.print( 'The contents of your .gitignore file for the project ' 'will be automatically loaded as the files to ignore.', color='green') ignore_globs = get_gitignore_glob(project_dir) if non_interactive and not ignore_globs: ignore_globs = [] if ignore_globs is None: printer.print(GLOB_HELP) file_path_completer.activate(seed_dir=project_dir) ignore_globs = ask_question( 'Which files do you want coala to ignore inside the ' 'project directory?', printer=printer, typecast=list) file_path_completer.deactivate() printer.print() ignore_globs = list(ignore_globs) escaped_project_dir = glob_escape(project_dir) file_path_globs = [ os.path.join(escaped_project_dir, glob_exp) for glob_exp in file_globs ] ignore_path_globs = [ os.path.join(escaped_project_dir, glob_exp) for glob_exp in ignore_globs ] ignore_path_globs.append(os.path.join(escaped_project_dir, '.git/**')) file_paths = collect_files(file_path_globs, log_printer, ignored_file_paths=ignore_path_globs) return file_paths, ignore_globs
def main(log_printer=None, section: Section = None): configure_logging() start_path = get_config_directory(section) if start_path is None: return 255 # start_path may have unintended glob characters orig_files = Globbing.glob(os.path.join( glob_escape(start_path), '**', '*.orig')) not_deleted = 0 for ofile in orig_files: logging.info('Deleting old backup file... ' + os.path.relpath(ofile)) try: os.remove(ofile) except OSError as oserror: not_deleted += 1 logging.warning("Couldn't delete {}. {}".format( os.path.relpath(ofile), oserror.strerror)) if not_deleted: logging.warning(str(not_deleted) + ' .orig backup files could not be' ' deleted, possibly because you ' 'lack the permission to do so. ' 'coala may not be able to create' ' backup files when patches are ' 'applied.') return 0
def icollect_bears(bear_dirs, bear_globs, kinds, log_printer): """ Collect all bears from bear directories that have a matching kind. :param bear_dirs: directory name or list of such that can contain bears :param bear_globs: globs of bears to collect :param kinds: list of bear kinds to be collected :param log_printer: log_printer to handle logging :return: iterator that yields a tuple with bear class and which bear_glob was used to find that bear class. """ for bear_dir, dir_glob in filter(lambda x: os.path.isdir(x[0]), icollect(bear_dirs)): # Since we get a real directory here and since we # pass this later to iglob, we need to escape this. bear_dir = glob_escape(bear_dir) for bear_glob in bear_globs: for matching_file in iglob( os.path.join(bear_dir, bear_glob + '.py')): try: for bear in _import_bears(matching_file, kinds): yield bear, bear_glob except BaseException as exception: log_printer.log_exception( "Unable to collect bears from {file}. Probably the " "file is malformed or the module code raises an " "exception.".format(file=matching_file), exception, log_level=LOG_LEVEL.WARNING)
def main(log_printer=None, section: Section = None): configure_logging() start_path = get_config_directory(section) log_printer = (LogPrinter(ConsolePrinter()) if log_printer is None else log_printer) if start_path is None: return 255 # start_path may have unintended glob characters orig_files = Globbing.glob( os.path.join(glob_escape(start_path), '**', '*.orig')) not_deleted = 0 for ofile in orig_files: log_printer.info('Deleting old backup file... ' + os.path.relpath(ofile)) try: os.remove(ofile) except OSError as oserror: not_deleted += 1 log_printer.warn("Couldn't delete {}. {}".format( os.path.relpath(ofile), oserror.strerror)) if not_deleted: log_printer.warn( str(not_deleted) + ' .orig backup files could not be' ' deleted, possibly because you lack the permission' ' to do so. coala may not be able to create' ' backup files when patches are applied.') return 0
def icollect_bears(bear_dir_glob, bear_globs, kinds, log_printer=None): """ Collect all bears from bear directories that have a matching kind. :param bear_dir_glob: Directory globs or list of such that can contain bears :param bear_globs: Globs of bears to collect :param kinds: List of bear kinds to be collected :param log_printer: Log_printer to handle logging :return: Iterator that yields a tuple with bear class and which bear_glob was used to find that bear class. """ for bear_dir, dir_glob in filter(lambda x: os.path.isdir(x[0]), icollect(bear_dir_glob)): # Since we get a real directory here and since we # pass this later to iglob, we need to escape this. bear_dir = glob_escape(bear_dir) for bear_glob in bear_globs: matching_files = iglob(os.path.join(bear_dir, bear_glob + '.py')) matching_files = sorted(matching_files) for matching_file in matching_files: try: for bear in _import_bears(matching_file, kinds): yield bear, bear_glob except pkg_resources.VersionConflict as exception: log_exception( (f'Unable to collect bears from {matching_file} ' 'because there ' 'is a conflict with the version of a dependency ' 'you have installed. This may be resolved by ' 'creating a separate virtual environment for coala ' f'or running `pip3 install \"{exception.req}\"`. ' 'Be aware that ' 'the latter solution might break other python ' 'packages that depend on the currently installed ' 'version.'), exception, log_level=LOG_LEVEL.WARNING) except BaseException as exception: log_exception( f'Unable to collect bears from {matching_file}. ' 'Probably the ' 'file is malformed or the module code raises an ' 'exception.', exception, log_level=LOG_LEVEL.WARNING)
def get_project_files(log_printer, printer, project_dir): """ Gets the list of files matching files in the user's project directory after prompting for glob expressions. :param log_printer: A ``LogPrinter`` object. :param printer: A ``ConsolePrinter`` object. :return: A list of file paths matching the files. """ file_globs = ["**"] ignore_globs = None if os.path.isfile(os.path.join(project_dir, ".gitignore")): printer.print( "The contents of your .gitignore file for the project " "will be automatically loaded as the files to ignore.", color="green") ignore_globs = get_gitignore_glob(project_dir) if ignore_globs is None: printer.print(GLOB_HELP) ignore_globs = ask_question("Which files do you want coala to ignore?", printer=printer, typecast=list) printer.print() escaped_project_dir = glob_escape(project_dir) file_path_globs = [ os.path.join(escaped_project_dir, glob_exp) for glob_exp in file_globs ] ignore_path_globs = [ os.path.join(escaped_project_dir, glob_exp) for glob_exp in ignore_globs ] ignore_path_globs.append(os.path.join(escaped_project_dir, ".git/**")) file_paths = collect_files(file_path_globs, log_printer, ignored_file_paths=ignore_path_globs) return file_paths, ignore_globs
def icollect_bears(bear_dir_glob, bear_globs, kinds, log_printer=None): """ Collect all bears from bear directories that have a matching kind. :param bear_dir_glob: Directory globs or list of such that can contain bears :param bear_globs: Globs of bears to collect :param kinds: List of bear kinds to be collected :param log_printer: Log_printer to handle logging :return: Iterator that yields a tuple with bear class and which bear_glob was used to find that bear class. """ for bear_dir, dir_glob in filter(lambda x: os.path.isdir(x[0]), icollect(bear_dir_glob)): # Since we get a real directory here and since we # pass this later to iglob, we need to escape this. bear_dir = glob_escape(bear_dir) for bear_glob in bear_globs: matching_files = iglob(os.path.join(bear_dir, bear_glob + '.py')) matching_files = sorted(matching_files) for matching_file in matching_files: try: for bear in _import_bears(matching_file, kinds): yield bear, bear_glob except pkg_resources.VersionConflict as exception: log_exception( ('Unable to collect bears from {file} because there ' 'is a conflict with the version of a dependency ' 'you have installed. This may be resolved by ' 'creating a separate virtual environment for coala ' 'or running `pip3 install \"{pkg}\"`. Be aware that ' 'the latter solution might break other python ' 'packages that depend on the currently installed ' 'version.').format(file=matching_file, pkg=exception.req), exception, log_level=LOG_LEVEL.WARNING) except BaseException as exception: log_exception( 'Unable to collect bears from {file}. Probably the ' 'file is malformed or the module code raises an ' 'exception.'.format(file=matching_file), exception, log_level=LOG_LEVEL.WARNING)
def icollect_bears(bear_dir_glob, bear_globs, kinds, log_printer): """ Collect all bears from bear directories that have a matching kind. :param bear_dir_glob: Directory globs or list of such that can contain bears :param bear_globs: Globs of bears to collect :param kinds: List of bear kinds to be collected :param log_printer: Log_printer to handle logging :return: Iterator that yields a tuple with bear class and which bear_glob was used to find that bear class. """ for bear_dir, dir_glob in filter(lambda x: os.path.isdir(x[0]), icollect(bear_dir_glob)): # Since we get a real directory here and since we # pass this later to iglob, we need to escape this. bear_dir = glob_escape(bear_dir) for bear_glob in bear_globs: for matching_file in iglob( os.path.join(bear_dir, bear_glob + '.py')): try: for bear in _import_bears(matching_file, kinds): yield bear, bear_glob except pkg_resources.VersionConflict as exception: log_printer.log_exception( ("Unable to collect bears from {file} because there " "is a conflict with the version of a dependency " "you have installed. This may be resolved by " "creating a separate virtual environment for coala " "or running `pip install {pkg}`. Be aware that the " "latter solution might break other python packages " "that depend on the currently installed " "version.").format(file=matching_file, pkg=exception.req), exception, log_level=LOG_LEVEL.WARNING) except BaseException as exception: log_printer.log_exception( "Unable to collect bears from {file}. Probably the " "file is malformed or the module code raises an " "exception.".format(file=matching_file), exception, log_level=LOG_LEVEL.WARNING)
def icollect_bears(bear_dirs, bear_globs, kinds, log_printer): """ Collect all bears from bear directories that have a matching kind. :param bear_dirs: directory name or list of such that can contain bears :param bear_globs: globs of bears to collect :param kinds: list of bear kinds to be collected :param log_printer: log_printer to handle logging :return: iterator that yields a tuple with bear class and which bear_glob was used to find that bear class. """ for bear_dir, dir_glob in filter(lambda x: os.path.isdir(x[0]), icollect(bear_dirs)): # Since we get a real directory here and since we # pass this later to iglob, we need to escape this. bear_dir = glob_escape(bear_dir) for bear_glob in bear_globs: for matching_file in iglob( os.path.join(bear_dir, bear_glob + '.py')): try: for bear in _import_bears(matching_file, kinds): yield bear, bear_glob except pkg_resources.VersionConflict as exception: log_printer.log_exception( ("Unable to collect bears from {file} because there " "is a conflict with the version of a dependency " "you have installed. This may be resolved by " "creating a separate virtual environment for coala " "or running `pip install {pkg}`. Be aware that the " "latter solution might break other python packages " "that depend on the currently installed " "version.").format(file=matching_file, pkg=exception.req), exception, log_level=LOG_LEVEL.WARNING) except BaseException as exception: log_printer.log_exception( "Unable to collect bears from {file}. Probably the " "file is malformed or the module code raises an " "exception.".format(file=matching_file), exception, log_level=LOG_LEVEL.WARNING)
def get_project_files(log_printer, printer, project_dir): """ Gets the list of files matching files in the user's project directory after prompting for glob expressions. :param log_printer: A ``LogPrinter`` object. :param printer: A ``ConsolePrinter`` object. :return: A list of file paths matching the files. """ printer.print(GLOB_HELP) file_globs = ask_question( "Which files do you want coala to run on?", default="**", printer=printer, typecast=list) ignore_globs = ask_question( "Which files do you want coala to run on?", printer=printer, typecast=list) printer.print() escaped_project_dir = glob_escape(project_dir) file_path_globs = [os.path.join( escaped_project_dir, glob_exp) for glob_exp in file_globs] ignore_path_globs = [os.path.join( escaped_project_dir, glob_exp) for glob_exp in ignore_globs] file_paths = collect_files( file_path_globs, log_printer, ignored_file_paths=ignore_path_globs) return file_paths
def __path__(self, origin=None, glob_escape_origin=False): """ Determines the path of this setting. Note: You can also use this function on strings, in that case the origin argument will be taken in every case. :param origin: The origin file to take if no origin is specified for the given setting. If you want to provide a directory, make sure it ends with a directory separator. :param glob_escape_origin: When this is set to true, the origin of this setting will be escaped with ``glob_escape``. :return: An absolute path. :raises ValueError: If no origin is specified in the setting nor the given origin parameter. """ strrep = str(self).strip() if os.path.isabs(strrep): return strrep if hasattr(self, "origin") and self.origin != "": origin = self.origin if origin is None: raise ValueError("Cannot determine path without origin.") # We need to get full path before escaping since the full path # may introduce unintended glob characters origin = os.path.abspath(os.path.dirname(origin)) if glob_escape_origin: origin = glob_escape(origin) return os.path.normpath(os.path.join(origin, strrep))
def __path__(self, origin=None, glob_escape_origin=False): """ Determines the path of this setting. Note: You can also use this function on strings, in that case the origin argument will be taken in every case. :param origin: The origin file to take if no origin is specified for the given setting. If you want to provide a directory, make sure it ends with a directory separator. :param glob_escape_origin: When this is set to true, the origin of this setting will be escaped with ``glob_escape``. :return: An absolute path. :raises ValueError: If no origin is specified in the setting nor the given origin parameter. """ strrep = str(self).strip() if os.path.isabs(strrep): return strrep if hasattr(self, 'origin') and self.origin != '': origin = self.origin if origin is None: raise ValueError('Cannot determine path without origin.') # We need to get full path before escaping since the full path # may introduce unintended glob characters origin = os.path.abspath(os.path.dirname(origin)) if glob_escape_origin: origin = glob_escape(origin) return os.path.normpath(os.path.join(origin, strrep))
def test_glob(self): self.uut = Setting("key", ".", origin=os.path.join("test (1)", "somefile")) self.assertEqual(glob(self.uut), glob_escape(os.path.abspath("test (1)")))
def get_project_files(log_printer, printer, project_dir, file_path_completer, non_interactive=False): """ Gets the list of files matching files in the user's project directory after prompting for glob expressions. :param log_printer: A ``LogPrinter`` object. :param printer: A ``ConsolePrinter`` object. :param file_path_completer: A ``file_path_completer`` object. :param non_interactive Whether coala-quickstart is in non-interactive mode :return: A list of file paths matching the files. """ file_globs = ['**'] ignore_globs = None gitignore_dir_list = [] for dir_name, subdir_name, file_list in os.walk(project_dir): if os.path.isfile(os.path.join(dir_name, '.gitignore')): gitignore_dir_list += [dir_name] if gitignore_dir_list: printer.print('The contents of your .gitignore file for the project ' 'will be automatically loaded as the files to ignore.', color='green') ignore_globs = get_gitignore_glob(project_dir, gitignore_dir_list) if non_interactive and not ignore_globs: ignore_globs = [] if ignore_globs is None: printer.print(GLOB_HELP) file_path_completer.activate(seed_dir=project_dir) ignore_globs = ask_question( 'Which files do you want coala to ignore inside the ' 'project directory?', printer=printer, typecast=list) file_path_completer.deactivate() printer.print() ignore_globs = list(ignore_globs) escaped_project_dir = glob_escape(project_dir) file_path_globs = [os.path.join( escaped_project_dir, glob_exp) for glob_exp in file_globs] ignore_path_globs = [os.path.join( escaped_project_dir, glob_exp) for glob_exp in ignore_globs] ignore_path_globs.append(os.path.join(escaped_project_dir, '.git/**')) file_paths = collect_files( file_path_globs, log_printer, ignored_file_paths=ignore_path_globs) return file_paths, ignore_globs