def get_line_types(repo, repo_uri, rev, path): """Returns an array, where each item means a line of code. Each item is labled 'code', 'comment' or 'empty'""" #profiler_start("Processing LineTypes for revision %s:%s", (self.rev, self.file_path)) uri = os.path.join(repo_uri, path) # concat repo_uri and file_path for full path file_content = _get_file_content(repo, uri, rev) # get file_content if file_content is None or file_content == '': printerr("[get_line_types] Error: No file content for " + str(rev) + ":" + str(path) + " found! Skipping.") line_types = None else: try: lexer = get_lexer_for_filename(path) except ClassNotFound: try: printdbg("[get_line_types] Guessing lexer for" + str(rev) + ":" + str(path) + ".") lexer = guess_lexer(file_content) except ClassNotFound: printdbg("[get_line_types] No guess or lexer found for " + str(rev) + ":" + str(path) + ". Using TextLexer instead.") lexer = TextLexer() if isinstance(lexer, NemerleLexer): # this lexer is broken and yield an unstoppable process # see https://bitbucket.org/birkenfeld/pygments-main/issue/706/nemerle-lexer-ends-in-an-infinite-loop lexer = TextLexer() # Not shure if this should be skipped, when the language uses off-side rules (e.g. python, # see http://en.wikipedia.org/wiki/Off-side_rule for list) stripped_code = _strip_lines(file_content) lexer_output = _iterate_lexer_output(lexer.get_tokens(stripped_code)) line_types_str = _comment_empty_or_code(lexer_output) line_types = line_types_str.split("\n") return line_types
def print_lines(console_printer, file_dict, sourcerange): """ Prints the lines between the current and the result line. If needed they will be shortened. :param console_printer: Object to print messages on the console. :param file_dict: A dictionary containing all files as values with filenames as key. :param sourcerange: The SourceRange object referring to the related lines to print. """ no_color = not console_printer.print_colored for i in range(sourcerange.start.line, sourcerange.end.line + 1): # Print affected file's line number in the sidebar. console_printer.print(format_lines(lines='', line_nr=i, symbol='['), color=FILE_LINES_COLOR, end='') line = file_dict[sourcerange.file][i - 1].rstrip('\n') try: lexer = get_lexer_for_filename(sourcerange.file) except ClassNotFound: lexer = TextLexer() lexer.add_filter(VisibleWhitespaceFilter( spaces=True, tabs=True, tabsize=SpacingHelper.DEFAULT_TAB_WIDTH)) # highlight() combines lexer and formatter to output a ``str`` # object. printed_chars = 0 if i == sourcerange.start.line and sourcerange.start.column: console_printer.print(highlight_text( no_color, line[:sourcerange.start.column - 1], BackgroundMessageStyle, lexer), end='') printed_chars = sourcerange.start.column - 1 if i == sourcerange.end.line and sourcerange.end.column: console_printer.print(highlight_text( no_color, line[printed_chars:sourcerange.end.column - 1], BackgroundSourceRangeStyle, lexer), end='') console_printer.print(highlight_text( no_color, line[sourcerange.end.column - 1:], BackgroundSourceRangeStyle, lexer), end='') console_printer.print('') else: console_printer.print(highlight_text( no_color, line[printed_chars:], BackgroundMessageStyle, lexer), end='') console_printer.print('')
def setUp(self): self.log_printer = ListLogPrinter() self.console_printer = ConsolePrinter(print_colored=False) self.no_color = not self.console_printer.print_colored self.file_diff_dict = {} self.section = Section('t') self.local_bears = OrderedDict([('default', [SomelocalBear]), ('test', [SomelocalBear])]) self.global_bears = OrderedDict([('default', [SomeglobalBear]), ('test', [SomeglobalBear])]) self.old_open_editor_applicable = OpenEditorAction.is_applicable OpenEditorAction.is_applicable = staticmethod( lambda *args: 'OpenEditorAction cannot be applied') self.old_apply_patch_applicable = ApplyPatchAction.is_applicable ApplyPatchAction.is_applicable = staticmethod( lambda *args: 'ApplyPatchAction cannot be applied') self.lexer = TextLexer() self.lexer.add_filter(VisibleWhitespaceFilter( spaces=True, tabs=True, tabsize=SpacingHelper.DEFAULT_TAB_WIDTH)) patcher = patch('coalib.results.result_actions.OpenEditorAction.' 'subprocess') self.addCleanup(patcher.stop) patcher.start()
def run(self): self.assert_has_content() try: lexer = get_lexer_by_name(self.arguments[0]) except ValueError: # no lexer found - use the text one instead of an exception lexer = TextLexer() lexer.add_filter(ctypes_types_highlighter) lexer.add_filter(custom_highlighters) # take an arbitrary option if more than one is given formatter = self.options and \ VARIANTS[self.options.keys()[0]] or \ DEFAULT print >>open('pygments.css', 'w'), formatter.get_style_defs('.highlight') parsed = highlight(u'\n'.join(self.content), lexer, formatter) return [nodes.raw('', parsed, format='html')]
def _parse_src(cls, src_contents, src_filename): """ Return a stream of `(token_type, value)` tuples parsed from `src_contents` (str) Uses `src_filename` to guess the type of file so it can highlight syntax correctly. """ # Parse the source into tokens try: lexer = guess_lexer_for_filename(src_filename, src_contents) except ClassNotFound: lexer = TextLexer() # Ensure that we don't strip newlines from # the source file when lexing. lexer.stripnl = False return pygments.lex(src_contents, lexer)
def _highlight(code, language, options, *, is_block, filters=[]): # Use our own lexer for ANSI if language == 'ansi': lexer = ansilexer.AnsiLexer() else: try: lexer = get_lexer_by_name(language) except ValueError: logger.warning( "No lexer found for language '{}', code highlighting disabled". format(language)) lexer = TextLexer() if (isinstance(lexer, BashSessionLexer) or isinstance(lexer, ansilexer.AnsiLexer)): class_ = 'm-console' else: class_ = 'm-code' if isinstance(lexer, ansilexer.AnsiLexer): formatter = ansilexer.HtmlAnsiFormatter(**options) else: formatter = HtmlFormatter(nowrap=True, **options) global filters_pre # First apply local pre filters, if any for filter in filters: f = filters_pre.get((lexer.name, filter)) if f: code = f(code) # Then a global pre filter, if any f = filters_pre.get(lexer.name) if f: code = f(code) parsed = highlight(code, lexer, formatter).rstrip() if not is_block: parsed.lstrip() global filters_post # First apply local post filters, if any for filter in filters: f = filters_post.get((lexer.name, filter)) if f: parsed = f(parsed) # Then a global post filter, if any f = filters_post.get(lexer.name) if f: parsed = f(parsed) return class_, parsed
def highlight_diff(code, _linenos=True): """Highlights an unified diff.""" diffs, info = prepare_udiff(code) if code and not diffs: # the diff was quite very much malformatted. # TODO: we do not yet support diffs made by GNU Diff! lexer = TextLexer() style = get_style(name_only=True) formatter = HtmlFormatter(linenos=_linenos, cssclass='syntax', style=style) return u'<div class="code">%s</div>' % \ pygments.highlight(code, lexer, formatter) return render_template('utils/udiff.html', diffs=diffs, info=info, linenos=_linenos)
def render_listing(in_name, out_name, folders=[], files=[]): if in_name: with open(in_name, 'r') as fd: try: lexer = get_lexer_for_filename(in_name) except: lexer = TextLexer() code = highlight(fd.read(), lexer, HtmlFormatter(cssclass='code', linenos="table", nowrap=False, lineanchors=utils.slugify(in_name, force=True), anchorlinenos=True)) # the pygments highlighter uses <div class="codehilite"><pre> # for code. We switch it to reST's <pre class="code">. code = CODERE.sub('<pre class="code literal-block">\\1</pre>', code) title = os.path.basename(in_name) else: code = '' title = os.path.split(os.path.dirname(out_name))[1] crumbs = utils.get_crumbs(os.path.relpath(out_name, kw['output_folder']), is_file=True) permalink = self.site.link( 'listing', os.path.relpath( out_name, os.path.join( kw['output_folder'], kw['listings_folder']))) if self.site.config['COPY_SOURCES']: source_link = permalink[:-5] else: source_link = None context = { 'code': code, 'title': title, 'crumbs': crumbs, 'permalink': permalink, 'lang': kw['default_lang'], 'folders': natsort.natsorted(folders), 'files': natsort.natsorted(files), 'description': title, 'source_link': source_link, } self.site.render_template('listing.tmpl', out_name, context)
def print_file_contents(self, contents, file_name, raw): if raw or not self.user_io.out.is_terminal: self.user_io.out.writeln(contents) return from pygments import highlight from pygments.lexers import PythonLexer, IniLexer, TextLexer from pygments.formatters import TerminalFormatter if file_name.endswith(".py"): lexer = PythonLexer() elif file_name.endswith(".txt"): lexer = IniLexer() else: lexer = TextLexer() self.user_io.out.write(highlight(contents, lexer, TerminalFormatter()))
def pygmentize(field, fctx, style, tmpl): # append a <link ...> to the syntax highlighting css old_header = tmpl.load('header') if SYNTAX_CSS not in old_header: new_header = old_header + SYNTAX_CSS tmpl.cache['header'] = new_header text = fctx.data() if util.binary(text): return # str.splitlines() != unicode.splitlines() because "reasons" for c in "\x0c\x1c\x1d\x1e": if c in text: text = text.replace(c, '') # Pygments is best used with Unicode strings: # <http://pygments.org/docs/unicode/> text = text.decode(encoding.encoding, 'replace') # To get multi-line strings right, we can't format line-by-line try: lexer = guess_lexer_for_filename(fctx.path(), text[:1024], stripnl=False) except (ClassNotFound, ValueError): try: lexer = guess_lexer(text[:1024], stripnl=False) except (ClassNotFound, ValueError): lexer = TextLexer(stripnl=False) formatter = HtmlFormatter(style=style) colorized = highlight(text, lexer, formatter) # strip wrapping div colorized = colorized[:colorized.find('\n</pre>')] colorized = colorized[colorized.find('<pre>') + 5:] coloriter = (s.encode(encoding.encoding, 'replace') for s in colorized.splitlines()) tmpl.filters['colorize'] = lambda x: coloriter.next() oldl = tmpl.cache[field] newl = oldl.replace('line|escape', 'line|colorize') tmpl.cache[field] = newl
def hilite(self): """ Pass code to the [Pygments](http://pygments.pocoo.org/) highliter with optional line numbers. The output should then be styled with css to your liking. No styles are applied by default - only styling hooks (i.e.: <span class="k">). returns : A string of html. """ self.src = self.src.strip('\n') if self.lang == None: self._getLang() if pygments: try: lexer = get_lexer_by_name(self.lang) except ValueError: try: lexer = guess_lexer(self.src) except ValueError: lexer = TextLexer() formatter = HtmlFormatter(linenos=self.linenos, cssclass=self.css_class, style=self.style, noclasses=self.noclasses) return highlight(self.src, lexer, formatter) else: # just escape and build markup usable by JS highlighting libs txt = self.src.replace('&', '&') txt = txt.replace('<', '<') txt = txt.replace('>', '>') txt = txt.replace('"', '"') classes = [] if self.lang: classes.append('language-%s' % self.lang) if self.linenos: classes.append('linenums') class_str = '' if classes: class_str = ' class="%s"' % ' '.join(classes) return '<pre class="%s"><code%s>%s</code></pre>\n'% \ (self.css_class, class_str, txt)
class HybridHttpLexer(Lexer): tl = TextLexer() hl = HttpLexer() def __init__(self, max_len=50000, *args, **kwargs): self.max_len = max_len Lexer.__init__(self, *args, **kwargs) def get_tokens_unprocessed(self, text): try: split = re.split(r"(?:\r\n|\n)(?:\r\n|\n)", text, 1) if len(split) == 2: h = split[0] body = split[1] else: h = split[0] body = '' except Exception as e: for v in self.tl.get_tokens_unprocessed(text): yield v raise e for token in self.hl.get_tokens_unprocessed(h): yield token if len(body) > 0: if len(body) <= self.max_len or self.max_len < 0: second_parser = None if "Content-Type" in h: try: ct = re.search("Content-Type: (.*)", h) if ct is not None: hval = ct.groups()[0] mime = hval.split(";")[0] second_parser = get_lexer_for_mimetype(mime) except ClassNotFound: pass if second_parser is None: yield (len(h), Token.Text, text[len(h):]) else: for index, tokentype, value in second_parser.get_tokens_unprocessed( text[len(h):]): yield (index + len(h), tokentype, value) else: yield (len(h), Token.Text, text[len(h):])
def run(self): self.assert_has_content() try: lexer = get_lexer_by_name(self.arguments[0]) except ValueError: # no lexer found - use the text one instead of an exception lexer = TextLexer() formatter = DEFAULT if self.options: options = dict((o, o in self.options) for o in OPTIONS) if not options.get('noclasses'): options['cssclass'] = 'code ' + PYGMENTS_STYLE formatter = HtmlFormatter(**options) parsed = highlight(u'\n'.join(self.content), lexer, formatter) return [nodes.raw('', parsed, format='html')]
def syntax_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """Prettify <syntax> snippets into marked up HTML blocks.""" try: lexer_name = arguments[0] lexer = get_lexer_by_name(lexer_name) except ValueError: lexer_name = 'txt' lexer = TextLexer() formatter = HtmlFormatter(cssclass='syntax %s' % lexer_name, lineseparator='<br/>') return [ nodes.raw('', highlight(u'\n'.join(content), lexer, formatter), format='html') ]
def pygments_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): if 'filename' in options: if options['filename']: content = [line.rstrip('\n') for line in file(options['filename'])] del options['filename'] try: lexer = get_lexer_by_name(arguments[0]) except ValueError: # no lexer found - use the text one instead of an exception lexer = TextLexer() # take an arbitrary option if more than one is given formatter = options and VARIANTS[options.keys()[0]] or DEFAULT parsed = highlight(u'\n'.join(content), lexer, formatter) return [nodes.raw('', parsed, format='html')]
def hilite(self): """ Pass code to the [Pygments](http://pygments.pocoo.org/) highliter with optional line numbers. The output should then be styled with css to your liking. No styles are applied by default - only styling hooks (i.e.: <span class="k">). returns : A string of html. """ self.src = self.src.strip('\n') if self.lang == None: self._getLang() try: from pygments import highlight from pygments.lexers import get_lexer_by_name, guess_lexer, \ TextLexer from pygments.formatters import HtmlFormatter except ImportError: # just escape and pass through txt = self._escape(self.src) if self.linenos: txt = self._number(txt) else: txt = '<div class="%s"><pre>%s</pre></div>\n'% \ (self.css_class, txt) return txt else: try: lexer = get_lexer_by_name(self.lang) except ValueError: try: lexer = guess_lexer(self.src) except ValueError: lexer = TextLexer() formatter = HtmlFormatter(linenos=self.linenos, cssclass=self.css_class, style=self.style, noclasses=self.noclasses) return highlight(self.src, lexer, formatter)
def run(self): """ Extend "run method" of Pygments class. Adapt the <pre> output to the HTML structure of Ace_editor. """ self.assert_has_content() try: lexer = get_lexer_by_name(self.arguments[0]) except ValueError: # no lexer found - use the text one instead of an exception lexer = TextLexer() # Fetch the defaults if pys.PYGMENTS_RST_OPTIONS is not None: for k, v in six.iteritems(pys.PYGMENTS_RST_OPTIONS): # Locally set options overrides the defaults if k not in self.options: self.options[k] = v if ('linenos' in self.options and self.options['linenos'] not in ('table', 'inline')): if self.options['linenos'] == 'none': self.options.pop('linenos') else: self.options['linenos'] = 'table' for flag in ('nowrap', 'nobackground', 'anchorlinenos'): if flag in self.options: self.options[flag] = True # noclasses should already default to False, but just in case... formatter = HtmlFormatter(noclasses=False, **self.options) parsed = highlight('\n'.join(self.content), lexer, formatter) parsed = parsed.replace( '<div class="highlight"><pre>', ''.join(( '<pre class="highlight">', '<code class="language-%s">' % lexer.name.lower() )) ) parsed = parsed.replace('</pre></div>', '</code></pre>') return [nodes.raw('', parsed, format='html')]
def create(type): valid = True postproc = None if type == 'py': lexer = PythonLexer() formatter = PyeFormatter(style=PyeDefaultStyle) elif type == 'c' or type == 'h': #lexer = CLexer() lexer = PyeCLexer() #postproc = CPostProc formatter = PyeFormatter(style=PyeDefaultStyle) elif type == 'java': #lexer = CLexer() lexer = JavaLexer() formatter = PyeFormatter(style=PyeDefaultStyle) else: debug("Cannot create a syntax highligher for '{}'... using TextLexer". format(type)) lexer = TextLexer() formatter = PyeFormatter(style=PyeTextStyle) def fmt_handler(data, regions): #debug("regions: {}".format(regions)) try: formatter.set_highlight_regions(regions) highlight(data, lexer, formatter) ret = formatter.get_formatted(data) #debug("fmt handler result: {}".format(ret)) except Exception as e: exc_type, exc_value, exc_traceback = sys.exc_info() lines = traceback.format_exception(exc_type, exc_value, exc_traceback) debug(''.join(line for line in lines)) return None return ret return fmt_handler
def render_listing(in_name, out_name, input_folder, output_folder, folders=[], files=[]): if in_name: with open(in_name, 'r') as fd: try: lexer = get_lexer_for_filename(in_name) except: lexer = TextLexer() code = highlight(fd.read(), lexer, utils.NikolaPygmentsHTML(in_name)) title = os.path.basename(in_name) else: code = '' title = os.path.split(os.path.dirname(out_name))[1] crumbs = utils.get_crumbs(os.path.relpath(out_name, self.kw['output_folder']), is_file=True) permalink = self.site.link( 'listing', os.path.join( input_folder, os.path.relpath( out_name[:-5], # remove '.html' os.path.join( self.kw['output_folder'], output_folder)))) if self.site.config['COPY_SOURCES'] and in_name: source_link = permalink[:-5] # remove '.html' else: source_link = None context = { 'code': code, 'title': title, 'crumbs': crumbs, 'permalink': permalink, 'lang': self.kw['default_lang'], 'folders': natsort.natsorted( folders, alg=natsort.ns.F | natsort.ns.IC), 'files': natsort.natsorted( files, alg=natsort.ns.F | natsort.ns.IC), 'description': title, 'source_link': source_link, } self.site.render_template('listing.tmpl', out_name, context)
def run(self): self.assert_has_content() set_classes(self.options) classes = ['m-code'] if 'classes' in self.options: classes += self.options['classes'] del self.options['classes'] try: lexer = get_lexer_by_name(self.arguments[0]) except ValueError: lexer = TextLexer() formatter = HtmlFormatter(nowrap=True, **self.options) parsed = highlight('\n'.join(self.content), lexer, formatter) content = nodes.raw('', parsed, format='html') pre = nodes.literal_block('', classes=classes) pre.append(content) return [pre]
def _highlight(code, language, options): # Use our own lexer for ANSI if language == 'ansi': lexer = ansilexer.AnsiLexer() else: try: lexer = get_lexer_by_name(language) except ValueError: logger.warning("No lexer found for language '{}', code highlighting disabled".format(language)) lexer = TextLexer() if (isinstance(lexer, BashSessionLexer) or isinstance(lexer, ansilexer.AnsiLexer)): class_ = 'm-console' else: class_ = 'm-code' formatter = HtmlFormatter(nowrap=True, **options) parsed = highlight(code, lexer, formatter).strip() return class_, parsed
def setUp(self): self.log_printer = LogPrinter(ConsolePrinter(print_colored=False)) self.console_printer = ConsolePrinter(print_colored=False) self.file_diff_dict = {} self.section = Section("t") self.local_bears = OrderedDict([("default", [SomelocalBear]), ("test", [SomelocalBear])]) self.global_bears = OrderedDict([("default", [SomeglobalBear]), ("test", [SomeglobalBear])]) self.old_open_editor_applicable = OpenEditorAction.is_applicable OpenEditorAction.is_applicable = staticmethod(lambda *args: False) self.old_apply_patch_applicable = ApplyPatchAction.is_applicable ApplyPatchAction.is_applicable = staticmethod(lambda *args: False) self.lexer = TextLexer() self.lexer.add_filter(VisibleWhitespaceFilter( spaces="•", tabs=True, tabsize=SpacingHelper.DEFAULT_TAB_WIDTH))
def run(self) : text = u'\n'.join(self.content) try : # Use the corresponding lexer, if a language was specified. lexer = get_lexer_by_name(self.arguments[0]) except IndexError : try : # No language was specified, so take an educated guess. lexer = guess_lexer(text) except ClassNotFound : # That didn't work either, use a standard TextLexer; no # highlighting. lexer = TextLexer() # Get current state from controller, supplied options. overrides = {} # overrides.update(self.controller.state) overrides.update(self.options) highlighted_text = highlight(text, lexer, HtmlFormatter(**overrides)) return [nodes.raw('', highlighted_text, format = 'html')]
def code(role, rawtext, text, lineno, inliner, options={}, content=[]): set_classes(options) classes = ['m-code'] if 'classes' in options: classes += options['classes'] del options['classes'] # Not sure why language is duplicated in classes? language = options.get('language', '') if language in classes: classes.remove(language) try: lexer = get_lexer_by_name(language) except ValueError: lexer = TextLexer() formatter = HtmlFormatter(nowrap=True) parsed = highlight(utils.unescape(text), lexer, formatter).strip() content = nodes.raw('', parsed, format='html') node = nodes.literal(rawtext, '', classes=classes, **options) node.append(content) return [node], []
def repl(m): # extract program from shebang argv = m.group('shebang').split() program = argv[0].split('/')[-1] if program == 'env' and len(argv) >= 2: program = argv[1] try: lexer = get_lexer_by_name(program) except ValueError: lexer = TextLexer() if INCLUDE_SHEBANG: code = m.group('codeblock') else: code = m.group('body') code = highlight(code, lexer, self.formatter) code = code.replace('\n\n', '\n \n').replace('\n', '<br />') return '\n\n<div class="code">%s</div>\n\n' % code
def run(self): self.assert_has_content() content = self.wrapped_content() if len(self.arguments) > 0: try: lexer = get_lexer_by_name(self.arguments[0]) except (ValueError, IndexError): # lexer not found, use default. lexer = TextLexer() else: lexer = guess_lexer(content) # import sys # print >>sys.stderr, self.arguments, lexer.__class__ # take an arbitrary option if more than one is given formatter = self.options and VARIANTS[self.options.keys() [0]] or DEFAULT parsed = highlight(content, lexer, formatter) return [nodes.raw('', parsed, format='html')]
def pygmentize(field, fctx, style, tmpl): # append a <link ...> to the syntax highlighting css old_header = ''.join(tmpl('header')) if SYNTAX_CSS not in old_header: new_header = old_header + SYNTAX_CSS tmpl.cache['header'] = new_header text = fctx.data() if util.binary(text): return # avoid UnicodeDecodeError in pygments text = encoding.tolocal(text) # To get multi-line strings right, we can't format line-by-line try: lexer = guess_lexer_for_filename(fctx.path(), text[:1024], encoding=encoding.encoding) except (ClassNotFound, ValueError): try: lexer = guess_lexer(text[:1024], encoding=encoding.encoding) except (ClassNotFound, ValueError): lexer = TextLexer(encoding=encoding.encoding) formatter = HtmlFormatter(style=style, encoding=encoding.encoding) colorized = highlight(text, lexer, formatter) # strip wrapping div colorized = colorized[:colorized.find('\n</pre>')] colorized = colorized[colorized.find('<pre>') + 5:] coloriter = iter(colorized.splitlines()) tmpl.filters['colorize'] = lambda x: coloriter.next() oldl = tmpl.cache[field] newl = oldl.replace('line|escape', 'line|colorize') tmpl.cache[field] = newl
def main(args=sys.argv): """ Main command line entry point. """ # pylint: disable-msg=R0911,R0912,R0915 usage = USAGE % ((args[0],) * 6) try: popts, args = getopt.getopt(args[1:], "l:f:F:o:O:P:LS:a:N:hVHgs") except getopt.GetoptError: print(usage, file=sys.stderr) return 2 opts = {} O_opts = [] P_opts = [] F_opts = [] for opt, arg in popts: if opt == "-O": O_opts.append(arg) elif opt == "-P": P_opts.append(arg) elif opt == "-F": F_opts.append(arg) opts[opt] = arg if opts.pop("-h", None) is not None: print(usage) return 0 if opts.pop("-V", None) is not None: print("Pygments version %s, (c) 2006-2014 by Georg Brandl." % __version__) return 0 # handle ``pygmentize -L`` L_opt = opts.pop("-L", None) if L_opt is not None: if opts: print(usage, file=sys.stderr) return 2 # print version main(["", "-V"]) if not args: args = ["lexer", "formatter", "filter", "style"] for arg in args: _print_list(arg.rstrip("s")) return 0 # handle ``pygmentize -H`` H_opt = opts.pop("-H", None) if H_opt is not None: if opts or len(args) != 2: print(usage, file=sys.stderr) return 2 what, name = args if what not in ("lexer", "formatter", "filter"): print(usage, file=sys.stderr) return 2 _print_help(what, name) return 0 # parse -O options parsed_opts = _parse_options(O_opts) opts.pop("-O", None) # parse -P options for p_opt in P_opts: try: name, value = p_opt.split("=", 1) except ValueError: parsed_opts[p_opt] = True else: parsed_opts[name] = value opts.pop("-P", None) # encodings inencoding = parsed_opts.get("inencoding", parsed_opts.get("encoding")) outencoding = parsed_opts.get("outencoding", parsed_opts.get("encoding")) # handle ``pygmentize -N`` infn = opts.pop("-N", None) if infn is not None: try: lexer = get_lexer_for_filename(infn, **parsed_opts) except ClassNotFound as err: lexer = TextLexer() except OptionError as err: print("Error:", err, file=sys.stderr) return 1 print(lexer.aliases[0]) return 0 # handle ``pygmentize -S`` S_opt = opts.pop("-S", None) a_opt = opts.pop("-a", None) if S_opt is not None: f_opt = opts.pop("-f", None) if not f_opt: print(usage, file=sys.stderr) return 2 if opts or args: print(usage, file=sys.stderr) return 2 try: parsed_opts["style"] = S_opt fmter = get_formatter_by_name(f_opt, **parsed_opts) except ClassNotFound as err: print(err, file=sys.stderr) return 1 arg = a_opt or "" try: print(fmter.get_style_defs(arg)) except Exception as err: print("Error:", err, file=sys.stderr) return 1 return 0 # if no -S is given, -a is not allowed if a_opt is not None: print(usage, file=sys.stderr) return 2 # parse -F options F_opts = _parse_filters(F_opts) opts.pop("-F", None) # select lexer lexer = opts.pop("-l", None) if lexer: try: lexer = get_lexer_by_name(lexer, **parsed_opts) except (OptionError, ClassNotFound) as err: print("Error:", err, file=sys.stderr) return 1 # read input code code = None if args: if len(args) > 1: print(usage, file=sys.stderr) return 2 if "-s" in opts: print("Error: -s option not usable when input file specified", file=sys.stderr) return 1 infn = args[0] try: with open(infn, "rb") as infp: code = infp.read() except Exception as err: print("Error: cannot read infile:", err, file=sys.stderr) return 1 if not inencoding: code, inencoding = guess_decode(code) # do we have to guess the lexer? if not lexer: try: lexer = get_lexer_for_filename(infn, code, **parsed_opts) except ClassNotFound as err: if "-g" in opts: try: lexer = guess_lexer(code, **parsed_opts) except ClassNotFound: lexer = TextLexer(**parsed_opts) else: print("Error:", err, file=sys.stderr) return 1 except OptionError as err: print("Error:", err, file=sys.stderr) return 1 elif "-s" not in opts: # treat stdin as full file (-s support is later) # read code from terminal, always in binary mode since we want to # decode ourselves and be tolerant with it if sys.version_info > (3,): # Python 3: we have to use .buffer to get a binary stream code = sys.stdin.buffer.read() else: code = sys.stdin.read() if not inencoding: code, inencoding = guess_decode_from_terminal(code, sys.stdin) # else the lexer will do the decoding if not lexer: try: lexer = guess_lexer(code, **parsed_opts) except ClassNotFound: lexer = TextLexer(**parsed_opts) # select formatter outfn = opts.pop("-o", None) fmter = opts.pop("-f", None) if fmter: try: fmter = get_formatter_by_name(fmter, **parsed_opts) except (OptionError, ClassNotFound) as err: print("Error:", err, file=sys.stderr) return 1 if outfn: if not fmter: try: fmter = get_formatter_for_filename(outfn, **parsed_opts) except (OptionError, ClassNotFound) as err: print("Error:", err, file=sys.stderr) return 1 try: outfile = open(outfn, "wb") except Exception as err: print("Error: cannot open outfile:", err, file=sys.stderr) return 1 else: if not fmter: fmter = TerminalFormatter(**parsed_opts) if sys.version_info > (3,): # Python 3: we have to use .buffer to get a binary stream outfile = sys.stdout.buffer else: outfile = sys.stdout # determine output encoding if not explicitly selected if not outencoding: if outfn: # output file? use lexer encoding for now (can still be None) fmter.encoding = inencoding else: # else use terminal encoding fmter.encoding = terminal_encoding(sys.stdout) # provide coloring under Windows, if possible if not outfn and sys.platform in ("win32", "cygwin") and fmter.name in ("Terminal", "Terminal256"): # unfortunately colorama doesn't support binary streams on Py3 if sys.version_info > (3,): import io outfile = io.TextIOWrapper(outfile, encoding=fmter.encoding) fmter.encoding = None try: import colorama.initialise except ImportError: pass else: outfile = colorama.initialise.wrap_stream(outfile, convert=None, strip=None, autoreset=False, wrap=True) # When using the LaTeX formatter and the option `escapeinside` is # specified, we need a special lexer which collects escaped text # before running the chosen language lexer. escapeinside = parsed_opts.get("escapeinside", "") if len(escapeinside) == 2 and isinstance(fmter, LatexFormatter): left = escapeinside[0] right = escapeinside[1] lexer = LatexEmbeddedLexer(left, right, lexer) # ... and do it! try: # process filters for fname, fopts in F_opts: lexer.add_filter(fname, **fopts) if "-s" not in opts: # process whole input as per normal... highlight(code, lexer, fmter, outfile) else: if not lexer: print("Error: when using -s a lexer has to be selected with -l", file=sys.stderr) return 1 # line by line processing of stdin (eg: for 'tail -f')... try: while 1: if sys.version_info > (3,): # Python 3: we have to use .buffer to get a binary stream line = sys.stdin.buffer.readline() else: line = sys.stdin.readline() if not line: break if not inencoding: line = guess_decode_from_terminal(line, sys.stdin)[0] highlight(line, lexer, fmter, outfile) if hasattr(outfile, "flush"): outfile.flush() except KeyboardInterrupt: return 0 except Exception: raise import traceback info = traceback.format_exception(*sys.exc_info()) msg = info[-1].strip() if len(info) >= 3: # extract relevant file and position info msg += "\n (f%s)" % info[-2].split("\n")[0].strip()[1:] print(file=sys.stderr) print("*** Error while highlighting:", file=sys.stderr) print(msg, file=sys.stderr) return 1 return 0
class ConsoleInteractionTest(unittest.TestCase): def setUp(self): self.log_printer = ListLogPrinter() self.console_printer = ConsolePrinter(print_colored=False) self.no_color = not self.console_printer.print_colored self.file_diff_dict = {} self.section = Section('t') self.local_bears = OrderedDict([('default', [SomelocalBear]), ('test', [SomelocalBear])]) self.global_bears = OrderedDict([('default', [SomeglobalBear]), ('test', [SomeglobalBear])]) self.old_open_editor_applicable = OpenEditorAction.is_applicable OpenEditorAction.is_applicable = staticmethod( lambda *args: 'OpenEditorAction cannot be applied') self.old_apply_patch_applicable = ApplyPatchAction.is_applicable ApplyPatchAction.is_applicable = staticmethod( lambda *args: 'ApplyPatchAction cannot be applied') self.lexer = TextLexer() self.lexer.add_filter(VisibleWhitespaceFilter( spaces=True, tabs=True, tabsize=SpacingHelper.DEFAULT_TAB_WIDTH)) def tearDown(self): OpenEditorAction.is_applicable = self.old_open_editor_applicable ApplyPatchAction.is_applicable = self.old_apply_patch_applicable def test_require_settings(self): curr_section = Section('') self.assertRaises(TypeError, acquire_settings, self.log_printer, 0, curr_section) with simulate_console_inputs(0, 1, 2) as generator: self.assertEqual(acquire_settings(self.log_printer, {'setting': ['help text', 'SomeBear']}, curr_section), {'setting': 0}) self.assertEqual(acquire_settings(self.log_printer, {'setting': ['help text', 'SomeBear', 'AnotherBear']}, curr_section), {'setting': 1}) self.assertEqual(acquire_settings(self.log_printer, {'setting': ['help text', 'SomeBear', 'AnotherBear', 'YetAnotherBear']}, curr_section), {'setting': 2}) self.assertEqual(generator.last_input, 2) def test_print_diffs_info(self): file_dict = {'a': ['a\n', 'b\n', 'c\n'], 'b': ['old_first\n']} diff_dict = {'a': Diff(file_dict['a']), 'b': Diff(file_dict['b'])} diff_dict['a'].add_lines(1, ['test\n']) diff_dict['a'].delete_line(3) diff_dict['b'].add_lines(0, ['first\n']) previous_diffs = {'a': Diff(file_dict['a'])} previous_diffs['a'].change_line(2, 'b\n', 'b_changed\n') with retrieve_stdout() as stdout: print_diffs_info(diff_dict, self.console_printer) self.assertEqual(stdout.getvalue(), '| | +1 -1 in a\n' '| | +1 -0 in b\n') @patch('coalib.output.ConsoleInteraction.acquire_actions_and_apply') @patch('coalib.output.ConsoleInteraction.ShowPatchAction.' 'apply_from_section') def test_print_result_interactive_small_patch(self, apply_from_section, _): file_dict = {'a': ['a\n', 'b\n', 'c\n'], 'b': ['old_first\n']} diff_dict = {'a': Diff(file_dict['a']), 'b': Diff(file_dict['b'])} diff_dict['a'].add_lines(1, ['test\n']) diff_dict['a'].delete_line(3) result = Result('origin', 'msg', diffs=diff_dict) section = Section('test') print_result(self.console_printer, section, self.file_diff_dict, result, file_dict, True) apply_from_section.assert_called_once_with( result, file_dict, self.file_diff_dict, section) @patch('coalib.output.ConsoleInteraction.acquire_actions_and_apply') @patch('coalib.output.ConsoleInteraction.print_diffs_info') def test_print_result_interactive_big_patch(self, diffs_info, _): file_dict = {'a': ['a\n', 'b\n', 'c\n'], 'b': ['old_first\n']} diff_dict = {'a': Diff(file_dict['a']), 'b': Diff(file_dict['b'])} diff_dict['a'].add_lines(1, ['test\n', 'test1\n', 'test2\n']) diff_dict['a'].delete_line(3) diff_dict['a'].add_lines(3, ['3test\n']) result = Result('origin', 'msg', diffs=diff_dict) section = Section('test') print_result(self.console_printer, section, self.file_diff_dict, result, file_dict, True) diffs_info.assert_called_once_with(diff_dict, self.console_printer) def test_print_result(self): print_result(self.console_printer, None, self.file_diff_dict, 'illegal value', {}) with simulate_console_inputs(0): print_result(self.console_printer, self.section, self.file_diff_dict, Result('origin', 'msg', diffs={}), {}) with make_temp() as testfile_path: file_dict = { testfile_path: ['1\n', '2\n', '3\n'], 'f_b': ['1', '2', '3'] } diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, '3\n', '3_changed\n') ApplyPatchAction.is_applicable = staticmethod( lambda *args: True) # Interaction must be closed by the user with `0` if it's not a # param with simulate_console_inputs('INVALID', -1, 1, 0, 3) as input_generator: curr_section = Section('') print_section_beginning(self.console_printer, curr_section) print_result(self.console_printer, curr_section, self.file_diff_dict, Result('origin', 'msg', diffs={ testfile_path: diff}), file_dict) self.assertEqual(input_generator.last_input, 3) self.file_diff_dict.clear() with open(testfile_path) as f: self.assertEqual(f.readlines(), ['1\n', '3_changed\n']) os.remove(testfile_path + '.orig') name, section = get_action_info(curr_section, TestAction().get_metadata(), failed_actions=set()) self.assertEqual(input_generator.last_input, 4) self.assertEqual(str(section), " {param : '3'}") self.assertEqual(name, 'TestAction') # Check if the user is asked for the parameter only the first time. # Use OpenEditorAction that needs this parameter (editor command). with simulate_console_inputs(1, 'test_editor', 0, 1, 0) as generator: OpenEditorAction.is_applicable = staticmethod(lambda *args: True) patch_result = Result('origin', 'msg', diffs={testfile_path: diff}) patch_result.file = 'f_b' print_result(self.console_printer, curr_section, self.file_diff_dict, patch_result, file_dict) # choose action, choose editor, choose no action (-1 -> 2) self.assertEqual(generator.last_input, 2) # It shoudn't ask for parameter again print_result(self.console_printer, curr_section, self.file_diff_dict, patch_result, file_dict) self.assertEqual(generator.last_input, 4) def test_print_affected_files(self): with retrieve_stdout() as stdout, \ make_temp() as some_file: file_dict = {some_file: ['1\n', '2\n', '3\n']} affected_code = (SourceRange.from_values(some_file),) print_affected_files(self.console_printer, self.log_printer, Result('origin', 'message', affected_code=affected_code), file_dict) self.assertEqual(stdout.getvalue(), '\n'+relpath(some_file)+'\n') def test_acquire_actions_and_apply(self): with make_temp() as testfile_path: file_dict = {testfile_path: ['1\n', '2\n', '3\n']} diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, '3\n', '3_changed\n') with simulate_console_inputs(1, 0) as generator, \ retrieve_stdout() as sio: ApplyPatchAction.is_applicable = staticmethod( lambda *args: True) acquire_actions_and_apply(self.console_printer, Section(''), self.file_diff_dict, Result('origin', 'message', diffs={ testfile_path: diff}), file_dict) self.assertEqual(generator.last_input, 1) self.assertIn(ApplyPatchAction.SUCCESS_MESSAGE, sio.getvalue()) class InvalidateTestAction(ResultAction): is_applicable = staticmethod(lambda *args: True) def apply(*args, **kwargs): ApplyPatchAction.is_applicable = staticmethod( lambda *args: 'ApplyPatchAction cannot be applied.') old_applypatch_is_applicable = ApplyPatchAction.is_applicable ApplyPatchAction.is_applicable = staticmethod(lambda *args: True) cli_actions = [ApplyPatchAction(), InvalidateTestAction()] with simulate_console_inputs(2, 1, 0) as generator, \ retrieve_stdout() as sio: acquire_actions_and_apply(self.console_printer, Section(''), self.file_diff_dict, Result('origin', 'message', diffs={testfile_path: diff}), file_dict, cli_actions=cli_actions) self.assertEqual(generator.last_input, 2) action_fail = 'Failed to execute the action' self.assertNotIn(action_fail, sio.getvalue()) apply_path_desc = ApplyPatchAction().get_metadata().desc self.assertEqual(sio.getvalue().count(apply_path_desc), 1) ApplyPatchAction.is_applicable = old_applypatch_is_applicable def test_ask_for_actions_and_apply(self): failed_actions = set() action = TestAction() args = [self.console_printer, Section(''), [action.get_metadata()], {'TestAction': action}, failed_actions, Result('origin', 'message'), {}, {}] with simulate_console_inputs(1, 'param1', 1, 'param2') as generator: action.apply = unittest.mock.Mock(side_effect=AssertionError) ask_for_action_and_apply(*args) self.assertEqual(generator.last_input, 1) self.assertIn('TestAction', failed_actions) action.apply = lambda *args, **kwargs: {} ask_for_action_and_apply(*args) self.assertEqual(generator.last_input, 3) self.assertNotIn('TestAction', failed_actions) def test_default_input(self): action = TestAction() args = [self.console_printer, Section(''), [action.get_metadata()], {'TestAction': action}, set(), Result('origin', 'message'), {}, {}] with simulate_console_inputs('') as generator: self.assertFalse(ask_for_action_and_apply(*args)) def test_print_result_no_input(self): with make_temp() as testfile_path: file_dict = {testfile_path: ['1\n', '2\n', '3\n']} diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, '3\n', '3_changed\n') with simulate_console_inputs(1, 2, 3) as generator, \ retrieve_stdout() as stdout: ApplyPatchAction.is_applicable = staticmethod( lambda *args: True) print_results_no_input(self.log_printer, Section('someSection'), [Result('origin', 'message', diffs={ testfile_path: diff})], file_dict, self.file_diff_dict, self.console_printer) self.assertEqual(generator.last_input, -1) self.assertEqual(stdout.getvalue(), """ Project wide: | | [NORMAL] origin: | | {}\n""".format(highlight_text(self.no_color, 'message', style=BackgroundMessageStyle))) def test_print_section_beginning(self): with retrieve_stdout() as stdout: print_section_beginning(self.console_printer, Section('name')) self.assertEqual(stdout.getvalue(), 'Executing section name...\n') def test_nothing_done(self): nothing_done(self.log_printer) self.assertEqual(['No existent section was targeted or enabled. ' 'Nothing to do.'], [log.message for log in self.log_printer.logs]) def test_print_results_empty(self): with retrieve_stdout() as stdout: print_results(self.log_printer, Section(''), [], {}, {}, self.console_printer) self.assertEqual(stdout.getvalue(), '') def test_print_results_project_wide(self): with retrieve_stdout() as stdout: print_results(self.log_printer, Section(''), [Result('origin', 'message')], {}, {}, self.console_printer) self.assertEqual( '\n{}\n| | [NORMAL] origin:\n| | {}\n'.format( STR_PROJECT_WIDE, highlight_text(self.no_color, 'message', style=BackgroundMessageStyle)), stdout.getvalue()) def test_print_results_for_file(self): with retrieve_stdout() as stdout: print_results( self.log_printer, Section(''), [Result.from_values('SpaceConsistencyBear', 'Trailing whitespace found', file='filename', line=2)], {abspath('filename'): ['test line\n', 'line 2\n', 'line 3\n']}, {}, self.console_printer) self.assertEqual("""\nfilename | 2| {} | | [NORMAL] SpaceConsistencyBear: | | {}\n""".format(highlight_text(self.no_color, 'line 2', self.lexer), highlight_text(self.no_color, 'Trailing whitespace found', style=BackgroundMessageStyle)), stdout.getvalue()) with retrieve_stdout() as stdout: print_results( self.log_printer, Section(''), [Result.from_values('SpaceConsistencyBear', 'Trailing whitespace found', file='filename', line=5)], {abspath('filename'): ['test line\n', 'line 2\n', 'line 3\n', 'line 4\n', 'line 5\n']}, {}, self.console_printer) self.assertEqual("""\nfilename | 5| {} | | [NORMAL] SpaceConsistencyBear: | | {}\n""".format(highlight_text(self.no_color, 'line 5', self.lexer), highlight_text(self.no_color, 'Trailing whitespace found', style=BackgroundMessageStyle)), stdout.getvalue()) def test_print_results_sorting(self): with retrieve_stdout() as stdout: print_results(self.log_printer, Section(''), [Result.from_values('SpaceConsistencyBear', 'Trailing whitespace found', file='file', line=5), Result.from_values('SpaceConsistencyBear', 'Trailing whitespace found', file='file', line=2)], {abspath('file'): ['test line\n', '\t\n', 'line 3\n', 'line 4\n', 'line 5\t\n']}, {}, self.console_printer) self.assertEqual(""" file | 2| {0} | | [NORMAL] SpaceConsistencyBear: | | {1} file | 5| {2} | | [NORMAL] SpaceConsistencyBear: | | {1}\n""".format(highlight_text(self.no_color, '\t', self.lexer), highlight_text(self.no_color, 'Trailing whitespace found', style=BackgroundMessageStyle), highlight_text(self.no_color, 'line 5\t', self.lexer)), stdout.getvalue()) def test_print_results_multiple_ranges(self): affected_code = ( SourceRange.from_values('some_file', 5, end_line=7), SourceRange.from_values('another_file', 1, 3, 1, 5), SourceRange.from_values('another_file', 3, 3, 3, 5)) with retrieve_stdout() as stdout: print_results( self.log_printer, Section(''), [Result('ClangCloneDetectionBear', 'Clone Found', affected_code)], {abspath('some_file'): ['line ' + str(i + 1) + '\n' for i in range(10)], abspath('another_file'): ['line ' + str(i + 1) for i in range(10)]}, {}, self.console_printer) self.assertEqual(""" another_file | 1| li{0}{1} another_file | 3| li{0}{2} some_file | 5| {3} | 6| {4} | 7| {5} | | [NORMAL] ClangCloneDetectionBear: | | {6}\n""".format(highlight_text(self.no_color, 'ne', self.lexer, BackgroundSourceRangeStyle), highlight_text(self.no_color, ' 1', self.lexer), highlight_text(self.no_color, ' 3', self.lexer), highlight_text(self.no_color, 'line 5', self.lexer), highlight_text(self.no_color, 'line 6', self.lexer), highlight_text(self.no_color, 'line 7', self.lexer), highlight_text(self.no_color, 'Clone Found', style=BackgroundMessageStyle)), stdout.getvalue()) def test_print_results_missing_file(self): self.log_printer.log_level = logging.CRITICAL with retrieve_stdout() as stdout: print_results( self.log_printer, Section(''), [Result('t', 'msg'), Result.from_values('t', 'msg', file='file', line=5)], {}, {}, self.console_printer) self.assertEqual('\n' + STR_PROJECT_WIDE + '\n' '| | [NORMAL] t:\n' '| | {0}\n' # Second results file isn't there, no context is # printed, only a warning log message which we # don't catch '| | [NORMAL] t:\n' '| | {0}\n'.format( highlight_text(self.no_color, 'msg', style=BackgroundMessageStyle)), stdout.getvalue()) def test_print_results_missing_line(self): with retrieve_stdout() as stdout: print_results( self.log_printer, Section(''), [Result.from_values('t', 'msg', file='file', line=5), Result.from_values('t', 'msg', file='file', line=6)], {abspath('file'): ['line ' + str(i + 1) for i in range(5)]}, {}, self.console_printer) self.assertEqual('\n' 'file\n' '| 5| {0}\n' '| | [NORMAL] t:\n' '| | {1}\n' '\n' 'file\n' '| 6| {2}\n' '| | [NORMAL] t:\n' '| | {1}\n'.format( highlight_text(self.no_color, 'line 5', self.lexer), highlight_text(self.no_color, 'msg', style=BackgroundMessageStyle), STR_LINE_DOESNT_EXIST), stdout.getvalue()) def test_print_results_without_line(self): with retrieve_stdout() as stdout: print_results( self.log_printer, Section(''), [Result.from_values('t', 'msg', file='file')], {abspath('file'): []}, {}, self.console_printer) self.assertEqual( '\nfile\n' '| | [NORMAL] t:\n' '| | {}\n'.format(highlight_text( self.no_color, 'msg', style=BackgroundMessageStyle)), stdout.getvalue())
infn = args[0] try: code = file(infn).read() except Exception, err: print >>sys.stderr, 'Error: cannot read infile:', err return 1 if not lexer: try: lexer = get_lexer_for_filename(infn, **parsed_opts) except ClassNotFound, err: if '-g' in opts: try: lexer = guess_lexer(code) except ClassNotFound: lexer = TextLexer() else: print >>sys.stderr, 'Error:', err return 1 except OptionError, err: print >>sys.stderr, 'Error:', err return 1 else: if '-g' in opts: code = sys.stdin.read() try: lexer = guess_lexer(code) except ClassNotFound: lexer = TextLexer() elif not lexer:
def main(args=sys.argv): """ Main command line entry point. """ # pylint: disable-msg=R0911,R0912,R0915 usage = USAGE % ((args[0],) * 6) if sys.platform in ['win32', 'cygwin']: try: # Provide coloring under Windows, if possible import colorama colorama.init() except ImportError: pass try: popts, args = getopt.getopt(args[1:], "l:f:F:o:O:P:LS:a:N:hVHg") except getopt.GetoptError: print(usage, file=sys.stderr) return 2 opts = {} O_opts = [] P_opts = [] F_opts = [] for opt, arg in popts: if opt == '-O': O_opts.append(arg) elif opt == '-P': P_opts.append(arg) elif opt == '-F': F_opts.append(arg) opts[opt] = arg if not opts and not args: print(usage) return 0 if opts.pop('-h', None) is not None: print(usage) return 0 if opts.pop('-V', None) is not None: print('Pygments version %s, (c) 2006-2014 by Georg Brandl.' % __version__) return 0 # handle ``pygmentize -L`` L_opt = opts.pop('-L', None) if L_opt is not None: if opts: print(usage, file=sys.stderr) return 2 # print version main(['', '-V']) if not args: args = ['lexer', 'formatter', 'filter', 'style'] for arg in args: _print_list(arg.rstrip('s')) return 0 # handle ``pygmentize -H`` H_opt = opts.pop('-H', None) if H_opt is not None: if opts or len(args) != 2: print(usage, file=sys.stderr) return 2 what, name = args if what not in ('lexer', 'formatter', 'filter'): print(usage, file=sys.stderr) return 2 _print_help(what, name) return 0 # parse -O options parsed_opts = _parse_options(O_opts) opts.pop('-O', None) # parse -P options for p_opt in P_opts: try: name, value = p_opt.split('=', 1) except ValueError: parsed_opts[p_opt] = True else: parsed_opts[name] = value opts.pop('-P', None) # handle ``pygmentize -N`` infn = opts.pop('-N', None) if infn is not None: try: lexer = get_lexer_for_filename(infn, **parsed_opts) except ClassNotFound as err: lexer = TextLexer() except OptionError as err: print('Error:', err, file=sys.stderr) return 1 print(lexer.aliases[0]) return 0 # handle ``pygmentize -S`` S_opt = opts.pop('-S', None) a_opt = opts.pop('-a', None) if S_opt is not None: f_opt = opts.pop('-f', None) if not f_opt: print(usage, file=sys.stderr) return 2 if opts or args: print(usage, file=sys.stderr) return 2 try: parsed_opts['style'] = S_opt fmter = get_formatter_by_name(f_opt, **parsed_opts) except ClassNotFound as err: print(err, file=sys.stderr) return 1 arg = a_opt or '' try: print(fmter.get_style_defs(arg)) except Exception as err: print('Error:', err, file=sys.stderr) return 1 return 0 # if no -S is given, -a is not allowed if a_opt is not None: print(usage, file=sys.stderr) return 2 # parse -F options F_opts = _parse_filters(F_opts) opts.pop('-F', None) # select formatter outfn = opts.pop('-o', None) fmter = opts.pop('-f', None) if fmter: try: fmter = get_formatter_by_name(fmter, **parsed_opts) except (OptionError, ClassNotFound) as err: print('Error:', err, file=sys.stderr) return 1 if outfn: if not fmter: try: fmter = get_formatter_for_filename(outfn, **parsed_opts) except (OptionError, ClassNotFound) as err: print('Error:', err, file=sys.stderr) return 1 try: outfile = open(outfn, 'wb') except Exception as err: print('Error: cannot open outfile:', err, file=sys.stderr) return 1 else: if not fmter: fmter = TerminalFormatter(**parsed_opts) outfile = sys.stdout # select lexer lexer = opts.pop('-l', None) if lexer: try: lexer = get_lexer_by_name(lexer, **parsed_opts) except (OptionError, ClassNotFound) as err: print('Error:', err, file=sys.stderr) return 1 if args: if len(args) > 1: print(usage, file=sys.stderr) return 2 infn = args[0] try: code = open(infn, 'rb').read() except Exception as err: print('Error: cannot read infile:', err, file=sys.stderr) return 1 if not lexer: try: lexer = get_lexer_for_filename(infn, code, **parsed_opts) except ClassNotFound as err: if '-g' in opts: try: lexer = guess_lexer(code, **parsed_opts) except ClassNotFound: lexer = TextLexer(**parsed_opts) else: print('Error:', err, file=sys.stderr) return 1 except OptionError as err: print('Error:', err, file=sys.stderr) return 1 else: if '-g' in opts: code = sys.stdin.read() try: lexer = guess_lexer(code, **parsed_opts) except ClassNotFound: lexer = TextLexer(**parsed_opts) elif not lexer: print('Error: no lexer name given and reading ' + \ 'from stdin (try using -g or -l <lexer>)', file=sys.stderr) return 2 else: code = sys.stdin.read() # No encoding given? Use latin1 if output file given, # stdin/stdout encoding otherwise. # (This is a compromise, I'm not too happy with it...) if 'encoding' not in parsed_opts and 'outencoding' not in parsed_opts: if outfn: # encoding pass-through fmter.encoding = 'latin1' else: if sys.version_info < (3,): # use terminal encoding; Python 3's terminals already do that lexer.encoding = getattr(sys.stdin, 'encoding', None) or 'ascii' fmter.encoding = getattr(sys.stdout, 'encoding', None) or 'ascii' elif not outfn and sys.version_info > (3,): # output to terminal with encoding -> use .buffer outfile = sys.stdout.buffer # ... and do it! try: # process filters for fname, fopts in F_opts: lexer.add_filter(fname, **fopts) highlight(code, lexer, fmter, outfile) except Exception: import traceback info = traceback.format_exception(*sys.exc_info()) msg = info[-1].strip() if len(info) >= 3: # extract relevant file and position info msg += '\n (f%s)' % info[-2].split('\n')[0].strip()[1:] print(file=sys.stderr) print('*** Error while highlighting:', file=sys.stderr) print(msg, file=sys.stderr) return 1 return 0
def main(args=sys.argv): """ Main command line entry point. """ # pylint: disable-msg=R0911,R0912,R0915 usage = USAGE % ((args[0],) * 6) if sys.platform in ["win32", "cygwin"]: try: # Provide coloring under Windows, if possible import colorama colorama.init() except ImportError: pass try: popts, args = getopt.getopt(args[1:], "l:f:F:o:O:P:LS:a:N:hVHg") except getopt.GetoptError as err: print(usage, file=sys.stderr) return 2 opts = {} O_opts = [] P_opts = [] F_opts = [] for opt, arg in popts: if opt == "-O": O_opts.append(arg) elif opt == "-P": P_opts.append(arg) elif opt == "-F": F_opts.append(arg) opts[opt] = arg if not opts and not args: print(usage) return 0 if opts.pop("-h", None) is not None: print(usage) return 0 if opts.pop("-V", None) is not None: print("Pygments version %s, (c) 2006-2013 by Georg Brandl." % __version__) return 0 # handle ``pygmentize -L`` L_opt = opts.pop("-L", None) if L_opt is not None: if opts: print(usage, file=sys.stderr) return 2 # print version main(["", "-V"]) if not args: args = ["lexer", "formatter", "filter", "style"] for arg in args: _print_list(arg.rstrip("s")) return 0 # handle ``pygmentize -H`` H_opt = opts.pop("-H", None) if H_opt is not None: if opts or len(args) != 2: print(usage, file=sys.stderr) return 2 what, name = args if what not in ("lexer", "formatter", "filter"): print(usage, file=sys.stderr) return 2 _print_help(what, name) return 0 # parse -O options parsed_opts = _parse_options(O_opts) opts.pop("-O", None) # parse -P options for p_opt in P_opts: try: name, value = p_opt.split("=", 1) except ValueError: parsed_opts[p_opt] = True else: parsed_opts[name] = value opts.pop("-P", None) # handle ``pygmentize -N`` infn = opts.pop("-N", None) if infn is not None: try: lexer = get_lexer_for_filename(infn, **parsed_opts) except ClassNotFound as err: lexer = TextLexer() except OptionError as err: print("Error:", err, file=sys.stderr) return 1 print(lexer.aliases[0]) return 0 # handle ``pygmentize -S`` S_opt = opts.pop("-S", None) a_opt = opts.pop("-a", None) if S_opt is not None: f_opt = opts.pop("-f", None) if not f_opt: print(usage, file=sys.stderr) return 2 if opts or args: print(usage, file=sys.stderr) return 2 try: parsed_opts["style"] = S_opt fmter = get_formatter_by_name(f_opt, **parsed_opts) except ClassNotFound as err: print(err, file=sys.stderr) return 1 arg = a_opt or "" try: print(fmter.get_style_defs(arg)) except Exception as err: print("Error:", err, file=sys.stderr) return 1 return 0 # if no -S is given, -a is not allowed if a_opt is not None: print(usage, file=sys.stderr) return 2 # parse -F options F_opts = _parse_filters(F_opts) opts.pop("-F", None) # select formatter outfn = opts.pop("-o", None) fmter = opts.pop("-f", None) if fmter: try: fmter = get_formatter_by_name(fmter, **parsed_opts) except (OptionError, ClassNotFound) as err: print("Error:", err, file=sys.stderr) return 1 if outfn: if not fmter: try: fmter = get_formatter_for_filename(outfn, **parsed_opts) except (OptionError, ClassNotFound) as err: print("Error:", err, file=sys.stderr) return 1 try: outfile = open(outfn, "wb") except Exception as err: print("Error: cannot open outfile:", err, file=sys.stderr) return 1 else: if not fmter: fmter = TerminalFormatter(**parsed_opts) outfile = sys.stdout # select lexer lexer = opts.pop("-l", None) if lexer: try: lexer = get_lexer_by_name(lexer, **parsed_opts) except (OptionError, ClassNotFound) as err: print("Error:", err, file=sys.stderr) return 1 if args: if len(args) > 1: print(usage, file=sys.stderr) return 2 infn = args[0] try: code = open(infn, "rb").read() except Exception as err: print("Error: cannot read infile:", err, file=sys.stderr) return 1 if not lexer: try: lexer = get_lexer_for_filename(infn, code, **parsed_opts) except ClassNotFound as err: if "-g" in opts: try: lexer = guess_lexer(code, **parsed_opts) except ClassNotFound: lexer = TextLexer(**parsed_opts) else: print("Error:", err, file=sys.stderr) return 1 except OptionError as err: print("Error:", err, file=sys.stderr) return 1 else: if "-g" in opts: code = sys.stdin.read() try: lexer = guess_lexer(code, **parsed_opts) except ClassNotFound: lexer = TextLexer(**parsed_opts) elif not lexer: print( "Error: no lexer name given and reading " + "from stdin (try using -g or -l <lexer>)", file=sys.stderr ) return 2 else: code = sys.stdin.read() # No encoding given? Use latin1 if output file given, # stdin/stdout encoding otherwise. # (This is a compromise, I'm not too happy with it...) if "encoding" not in parsed_opts and "outencoding" not in parsed_opts: if outfn: # encoding pass-through fmter.encoding = "latin1" else: if sys.version_info < (3,): # use terminal encoding; Python 3's terminals already do that lexer.encoding = getattr(sys.stdin, "encoding", None) or "ascii" fmter.encoding = getattr(sys.stdout, "encoding", None) or "ascii" elif not outfn and sys.version_info > (3,): # output to terminal with encoding -> use .buffer outfile = sys.stdout.buffer # ... and do it! try: # process filters for fname, fopts in F_opts: lexer.add_filter(fname, **fopts) highlight(code, lexer, fmter, outfile) except Exception as err: import traceback info = traceback.format_exception(*sys.exc_info()) msg = info[-1].strip() if len(info) >= 3: # extract relevant file and position info msg += "\n (f%s)" % info[-2].split("\n")[0].strip()[1:] print(file=sys.stderr) print("*** Error while highlighting:", file=sys.stderr) print(msg, file=sys.stderr) return 1 return 0
args = sys.argv[1:] if len(args) == 1: filename = args[0] content = codecs.open(args[0], "r", "utf-8").read() elif len(args) == 2: filename = args[0] assert args[1] == "-" content = sys.stdin.read() # Cheesy hack for override some false guesses by Pygments. # A better answer might be to look at lexing errors and try a secondary # guess. overrides = {"Makefile.py": ".py"} basename = basename(filename) try: lexer = get_lexer_for_filename(overrides.get(basename, filename), content) except ClassNotFound: try: lexer = guess_lexer(content) except ClassNotFound: lexer = TextLexer() sys.stderr.write("lexer: %r\n" % lexer) fmter = get_formatter_by_name("html") fmter.encoding = "utf-8" lexer.encoding = "utf-8" outfile = sys.stdout highlight(content, lexer, fmter, outfile)
def main_inner(popts, args, usage): opts = {} O_opts = [] P_opts = [] F_opts = [] for opt, arg in popts: if opt == '-O': O_opts.append(arg) elif opt == '-P': P_opts.append(arg) elif opt == '-F': F_opts.append(arg) opts[opt] = arg if opts.pop('-h', None) is not None: print(usage) return 0 if opts.pop('-V', None) is not None: print('Pygments version %s, (c) 2006-2014 by Georg Brandl.' % __version__) return 0 # handle ``pygmentize -L`` L_opt = opts.pop('-L', None) if L_opt is not None: if opts: print(usage, file=sys.stderr) return 2 # print version main(['', '-V']) if not args: args = ['lexer', 'formatter', 'filter', 'style'] for arg in args: _print_list(arg.rstrip('s')) return 0 # handle ``pygmentize -H`` H_opt = opts.pop('-H', None) if H_opt is not None: if opts or len(args) != 2: print(usage, file=sys.stderr) return 2 what, name = args if what not in ('lexer', 'formatter', 'filter'): print(usage, file=sys.stderr) return 2 return _print_help(what, name) # parse -O options parsed_opts = _parse_options(O_opts) opts.pop('-O', None) # parse -P options for p_opt in P_opts: try: name, value = p_opt.split('=', 1) except ValueError: parsed_opts[p_opt] = True else: parsed_opts[name] = value opts.pop('-P', None) # encodings inencoding = parsed_opts.get('inencoding', parsed_opts.get('encoding')) outencoding = parsed_opts.get('outencoding', parsed_opts.get('encoding')) # handle ``pygmentize -N`` infn = opts.pop('-N', None) if infn is not None: lexer = find_lexer_class_for_filename(infn) if lexer is None: lexer = TextLexer print(lexer.aliases[0]) return 0 # handle ``pygmentize -S`` S_opt = opts.pop('-S', None) a_opt = opts.pop('-a', None) if S_opt is not None: f_opt = opts.pop('-f', None) if not f_opt: print(usage, file=sys.stderr) return 2 if opts or args: print(usage, file=sys.stderr) return 2 try: parsed_opts['style'] = S_opt fmter = get_formatter_by_name(f_opt, **parsed_opts) except ClassNotFound as err: print(err, file=sys.stderr) return 1 print(fmter.get_style_defs(a_opt or '')) return 0 # if no -S is given, -a is not allowed if a_opt is not None: print(usage, file=sys.stderr) return 2 # parse -F options F_opts = _parse_filters(F_opts) opts.pop('-F', None) # select lexer lexer = None # given by name? lexername = opts.pop('-l', None) if lexername: try: lexer = get_lexer_by_name(lexername, **parsed_opts) except (OptionError, ClassNotFound) as err: print('Error:', err, file=sys.stderr) return 1 # read input code code = None if args: if len(args) > 1: print(usage, file=sys.stderr) return 2 if '-s' in opts: print('Error: -s option not usable when input file specified', file=sys.stderr) return 2 infn = args[0] try: with open(infn, 'rb') as infp: code = infp.read() except Exception as err: print('Error: cannot read infile:', err, file=sys.stderr) return 1 if not inencoding: code, inencoding = guess_decode(code) # do we have to guess the lexer? if not lexer: try: lexer = get_lexer_for_filename(infn, code, **parsed_opts) except ClassNotFound as err: if '-g' in opts: try: lexer = guess_lexer(code, **parsed_opts) except ClassNotFound: lexer = TextLexer(**parsed_opts) else: print('Error:', err, file=sys.stderr) return 1 except OptionError as err: print('Error:', err, file=sys.stderr) return 1 elif '-s' not in opts: # treat stdin as full file (-s support is later) # read code from terminal, always in binary mode since we want to # decode ourselves and be tolerant with it if sys.version_info > (3,): # Python 3: we have to use .buffer to get a binary stream code = sys.stdin.buffer.read() else: code = sys.stdin.read() if not inencoding: code, inencoding = guess_decode_from_terminal(code, sys.stdin) # else the lexer will do the decoding if not lexer: try: lexer = guess_lexer(code, **parsed_opts) except ClassNotFound: lexer = TextLexer(**parsed_opts) else: # -s option needs a lexer with -l if not lexer: print('Error: when using -s a lexer has to be selected with -l', file=sys.stderr) return 2 # process filters for fname, fopts in F_opts: try: lexer.add_filter(fname, **fopts) except ClassNotFound as err: print('Error:', err, file=sys.stderr) return 1 # select formatter outfn = opts.pop('-o', None) fmter = opts.pop('-f', None) if fmter: try: fmter = get_formatter_by_name(fmter, **parsed_opts) except (OptionError, ClassNotFound) as err: print('Error:', err, file=sys.stderr) return 1 if outfn: if not fmter: try: fmter = get_formatter_for_filename(outfn, **parsed_opts) except (OptionError, ClassNotFound) as err: print('Error:', err, file=sys.stderr) return 1 try: outfile = open(outfn, 'wb') except Exception as err: print('Error: cannot open outfile:', err, file=sys.stderr) return 1 else: if not fmter: fmter = TerminalFormatter(**parsed_opts) if sys.version_info > (3,): # Python 3: we have to use .buffer to get a binary stream outfile = sys.stdout.buffer else: outfile = sys.stdout # determine output encoding if not explicitly selected if not outencoding: if outfn: # output file? use lexer encoding for now (can still be None) fmter.encoding = inencoding else: # else use terminal encoding fmter.encoding = terminal_encoding(sys.stdout) # provide coloring under Windows, if possible if not outfn and sys.platform in ('win32', 'cygwin') and \ fmter.name in ('Terminal', 'Terminal256'): # pragma: no cover # unfortunately colorama doesn't support binary streams on Py3 if sys.version_info > (3,): from pygments.util import UnclosingTextIOWrapper outfile = UnclosingTextIOWrapper(outfile, encoding=fmter.encoding) fmter.encoding = None try: import colorama.initialise except ImportError: pass else: outfile = colorama.initialise.wrap_stream( outfile, convert=None, strip=None, autoreset=False, wrap=True) # When using the LaTeX formatter and the option `escapeinside` is # specified, we need a special lexer which collects escaped text # before running the chosen language lexer. escapeinside = parsed_opts.get('escapeinside', '') if len(escapeinside) == 2 and isinstance(fmter, LatexFormatter): left = escapeinside[0] right = escapeinside[1] lexer = LatexEmbeddedLexer(left, right, lexer) # ... and do it! if '-s' not in opts: # process whole input as per normal... highlight(code, lexer, fmter, outfile) return 0 else: # line by line processing of stdin (eg: for 'tail -f')... try: while 1: if sys.version_info > (3,): # Python 3: we have to use .buffer to get a binary stream line = sys.stdin.buffer.readline() else: line = sys.stdin.readline() if not line: break if not inencoding: line = guess_decode_from_terminal(line, sys.stdin)[0] highlight(line, lexer, fmter, outfile) if hasattr(outfile, 'flush'): outfile.flush() return 0 except KeyboardInterrupt: # pragma: no cover return 0
for p_opt in P_opts: try: name, value = p_opt.split("=", 1) except ValueError: parsed_opts[p_opt] = True else: parsed_opts[name] = value opts.pop("-P", None) # handle ``pygmentize -N`` infn = opts.pop("-N", None) if infn is not None: try: lexer = get_lexer_for_filename(infn, **parsed_opts) except ClassNotFound, err: lexer = TextLexer() except OptionError, err: print >> sys.stderr, "Error:", err return 1 print lexer.aliases[0] return 0 # handle ``pygmentize -S`` S_opt = opts.pop("-S", None) a_opt = opts.pop("-a", None) if S_opt is not None: f_opt = opts.pop("-f", None) if not f_opt: print >> sys.stderr, usage return 2
class ConsoleInteractionTest(unittest.TestCase): def setUp(self): self.log_printer = LogPrinter(ConsolePrinter(print_colored=False)) self.console_printer = ConsolePrinter(print_colored=False) self.file_diff_dict = {} self.section = Section("t") self.local_bears = OrderedDict([("default", [SomelocalBear]), ("test", [SomelocalBear])]) self.global_bears = OrderedDict([("default", [SomeglobalBear]), ("test", [SomeglobalBear])]) self.old_open_editor_applicable = OpenEditorAction.is_applicable OpenEditorAction.is_applicable = staticmethod(lambda *args: False) self.old_apply_patch_applicable = ApplyPatchAction.is_applicable ApplyPatchAction.is_applicable = staticmethod(lambda *args: False) self.lexer = TextLexer() self.lexer.add_filter(VisibleWhitespaceFilter( spaces="•", tabs=True, tabsize=SpacingHelper.DEFAULT_TAB_WIDTH)) def tearDown(self): OpenEditorAction.is_applicable = self.old_open_editor_applicable ApplyPatchAction.is_applicable = self.old_apply_patch_applicable def test_require_settings(self): self.assertRaises(TypeError, acquire_settings, self.log_printer, 0) with simulate_console_inputs(0, 1, 2) as generator: self.assertEqual(acquire_settings(self.log_printer, {"setting": ["help text", "SomeBear"]}), {"setting": 0}) self.assertEqual(acquire_settings(self.log_printer, {"setting": ["help text", "SomeBear", "AnotherBear"]}), {"setting": 1}) self.assertEqual(acquire_settings(self.log_printer, {"setting": ["help text", "SomeBear", "AnotherBear", "YetAnotherBear"]}), {"setting": 2}) self.assertEqual(generator.last_input, 2) def test_print_diffs_info(self): file_dict = {"a": ["a\n", "b\n", "c\n"], "b": ["old_first\n"]} diff_dict = {"a": Diff(file_dict['a']), "b": Diff(file_dict['b'])} diff_dict["a"].add_lines(1, ["test\n"]) diff_dict["a"].delete_line(3) diff_dict["b"].add_lines(0, ["first\n"]) previous_diffs = {"a": Diff(file_dict['a'])} previous_diffs["a"].change_line(2, "b\n", "b_changed\n") with retrieve_stdout() as stdout: print_diffs_info(diff_dict, self.console_printer) self.assertEqual(stdout.getvalue(), "| | +1 -1 in a\n" "| | +1 -0 in b\n") @patch("coalib.output.ConsoleInteraction.acquire_actions_and_apply") @patch("coalib.output.ConsoleInteraction.ShowPatchAction." "apply_from_section") def test_print_result_interactive_small_patch(self, apply_from_section, _): file_dict = {"a": ["a\n", "b\n", "c\n"], "b": ["old_first\n"]} diff_dict = {"a": Diff(file_dict['a']), "b": Diff(file_dict['b'])} diff_dict["a"].add_lines(1, ["test\n"]) diff_dict["a"].delete_line(3) result = Result("origin", "msg", diffs=diff_dict) section = Section("test") print_result(self.console_printer, self.log_printer, section, self.file_diff_dict, result, file_dict, True) apply_from_section.assert_called_once_with( result, file_dict, self.file_diff_dict, section) @patch("coalib.output.ConsoleInteraction.acquire_actions_and_apply") @patch("coalib.output.ConsoleInteraction.print_diffs_info") def test_print_result_interactive_big_patch(self, diffs_info, _): file_dict = {"a": ["a\n", "b\n", "c\n"], "b": ["old_first\n"]} diff_dict = {"a": Diff(file_dict['a']), "b": Diff(file_dict['b'])} diff_dict["a"].add_lines(1, ["test\n", "test1\n", "test2\n"]) diff_dict["a"].delete_line(3) diff_dict["a"].add_lines(3, ["3test\n"]) result = Result("origin", "msg", diffs=diff_dict) section = Section("test") print_result(self.console_printer, self.log_printer, section, self.file_diff_dict, result, file_dict, True) diffs_info.assert_called_once_with(diff_dict, self.console_printer) def test_print_result(self): print_result(self.console_printer, self.log_printer, None, self.file_diff_dict, "illegal value", {}) with simulate_console_inputs(0): print_result(self.console_printer, self.log_printer, self.section, self.file_diff_dict, Result("origin", "msg", diffs={}), {}) with make_temp() as testfile_path: file_dict = { testfile_path: ["1\n", "2\n", "3\n"], "f_b": ["1", "2", "3"] } diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, "3\n", "3_changed\n") ApplyPatchAction.is_applicable = staticmethod( lambda *args: True) # Interaction must be closed by the user with `0` if it's not a # param with simulate_console_inputs("INVALID", -1, 1, 0, 3) as input_generator: curr_section = Section("") print_section_beginning(self.console_printer, curr_section) print_result(self.console_printer, self.log_printer, curr_section, self.file_diff_dict, Result("origin", "msg", diffs={ testfile_path: diff}), file_dict) self.assertEqual(input_generator.last_input, 3) self.file_diff_dict.clear() with open(testfile_path) as f: self.assertEqual(f.readlines(), ["1\n", "3_changed\n"]) os.remove(testfile_path + ".orig") name, section = get_action_info(curr_section, TestAction().get_metadata(), failed_actions=set()) self.assertEqual(input_generator.last_input, 4) self.assertEqual(str(section), " {param : '3'}") self.assertEqual(name, "TestAction") # Check if the user is asked for the parameter only the first time. # Use OpenEditorAction that needs this parameter (editor command). with simulate_console_inputs(1, "test_editor", 0, 1, 0) as generator: OpenEditorAction.is_applicable = staticmethod(lambda *args: True) patch_result = Result("origin", "msg", diffs={testfile_path: diff}) patch_result.file = "f_b" print_result(self.console_printer, self.log_printer, curr_section, self.file_diff_dict, patch_result, file_dict) # choose action, choose editor, choose no action (-1 -> 2) self.assertEqual(generator.last_input, 2) # It shoudn't ask for parameter again print_result(self.console_printer, self.log_printer, curr_section, self.file_diff_dict, patch_result, file_dict) self.assertEqual(generator.last_input, 4) def test_print_affected_files(self): with retrieve_stdout() as stdout, \ make_temp() as some_file: file_dict = {some_file: ["1\n", "2\n", "3\n"]} affected_code = (SourceRange.from_values(some_file),) print_affected_files(self.console_printer, self.log_printer, Section(""), Result("origin", "message", affected_code=affected_code), file_dict, color=True) self.assertEqual(stdout.getvalue(), "\n"+relpath(some_file)+"\n") def test_acquire_actions_and_apply(self): with make_temp() as testfile_path: file_dict = {testfile_path: ["1\n", "2\n", "3\n"]} diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, "3\n", "3_changed\n") with simulate_console_inputs(1, 0) as generator, \ retrieve_stdout() as sio: ApplyPatchAction.is_applicable = staticmethod( lambda *args: True) acquire_actions_and_apply(self.console_printer, self.log_printer, Section(""), self.file_diff_dict, Result("origin", "message", diffs={ testfile_path: diff}), file_dict) self.assertEqual(generator.last_input, 1) self.assertIn(ApplyPatchAction.SUCCESS_MESSAGE, sio.getvalue()) class InvalidateTestAction(ResultAction): is_applicable = staticmethod(lambda *args: True) def apply(*args, **kwargs): ApplyPatchAction.is_applicable = staticmethod( lambda *args: False) old_applypatch_is_applicable = ApplyPatchAction.is_applicable ApplyPatchAction.is_applicable = staticmethod(lambda *args: True) cli_actions = [ApplyPatchAction(), InvalidateTestAction()] with simulate_console_inputs(2, 1, 0) as generator, \ retrieve_stdout() as sio: acquire_actions_and_apply(self.console_printer, self.log_printer, Section(""), self.file_diff_dict, Result("origin", "message", diffs={testfile_path: diff}), file_dict, cli_actions=cli_actions) self.assertEqual(generator.last_input, 2) action_fail = "Failed to execute the action" self.assertNotIn(action_fail, sio.getvalue()) apply_path_desc = ApplyPatchAction().get_metadata().desc self.assertEqual(sio.getvalue().count(apply_path_desc), 1) ApplyPatchAction.is_applicable = old_applypatch_is_applicable def test_ask_for_actions_and_apply(self): failed_actions = set() action = TestAction() args = [self.log_printer, self.console_printer, Section(""), [action.get_metadata()], {'TestAction': action}, failed_actions, Result("origin", "message"), {}, {}] with simulate_console_inputs(1, 'param1', 1, 'param2') as generator: action.apply = unittest.mock.Mock(side_effect=AssertionError) ask_for_action_and_apply(*args) self.assertEqual(generator.last_input, 1) self.assertIn('TestAction', failed_actions) action.apply = lambda *args, **kwargs: {} ask_for_action_and_apply(*args) self.assertEqual(generator.last_input, 3) self.assertNotIn('TestAction', failed_actions) def test_print_result_no_input(self): with make_temp() as testfile_path: file_dict = {testfile_path: ["1\n", "2\n", "3\n"]} diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, "3\n", "3_changed\n") with simulate_console_inputs(1, 2, 3) as generator, \ retrieve_stdout() as stdout: ApplyPatchAction.is_applicable = staticmethod( lambda *args: True) print_results_no_input(self.log_printer, Section("someSection"), [Result("origin", "message", diffs={ testfile_path: diff})], file_dict, self.file_diff_dict, color=False) self.assertEqual(generator.last_input, -1) self.assertEqual(stdout.getvalue(), """ Project wide: | | [NORMAL] origin: | | {}\n""".format(highlight_text("message", style=BackgroundMessageStyle))) def test_print_section_beginning(self): with retrieve_stdout() as stdout: print_section_beginning(self.console_printer, Section("name")) self.assertEqual(stdout.getvalue(), "Executing section name...\n") def test_nothing_done(self): with retrieve_stdout() as stdout: nothing_done(self.log_printer) self.assertIn("No existent section was targeted or enabled. " "Nothing to do.\n", stdout.getvalue()) def test_print_results_empty(self): with retrieve_stdout() as stdout: print_results(self.log_printer, Section(""), [], {}, {}) self.assertEqual(stdout.getvalue(), "") def test_print_results_project_wide(self): with retrieve_stdout() as stdout: print_results(self.log_printer, Section(""), [Result("origin", "message")], {}, {}, color=False) self.assertEqual( "\n{}\n| | [NORMAL] origin:\n| | {}\n".format( STR_PROJECT_WIDE, highlight_text("message", style=BackgroundMessageStyle)), stdout.getvalue()) def test_print_results_for_file(self): with retrieve_stdout() as stdout: print_results( self.log_printer, Section(""), [Result.from_values("SpaceConsistencyBear", "Trailing whitespace found", file="filename", line=2)], {abspath("filename"): ["test line\n", "line 2\n", "line 3\n"]}, {}, color=False) self.assertEqual("""\nfilename | 2| {} | | [NORMAL] SpaceConsistencyBear: | | {}\n""".format(highlight_text('line 2', self.lexer), highlight_text("Trailing whitespace found", style=BackgroundMessageStyle)), stdout.getvalue()) with retrieve_stdout() as stdout: print_results( self.log_printer, Section(""), [Result.from_values("SpaceConsistencyBear", "Trailing whitespace found", file="filename", line=5)], {abspath("filename"): ["test line\n", "line 2\n", "line 3\n", "line 4\n", "line 5\n"]}, {}, color=False) self.assertEqual("""\nfilename | 5| {} | | [NORMAL] SpaceConsistencyBear: | | {}\n""".format(highlight_text('line 5', self.lexer), highlight_text("Trailing whitespace found", style=BackgroundMessageStyle)), stdout.getvalue()) def test_print_results_sorting(self): with retrieve_stdout() as stdout: print_results(self.log_printer, Section(""), [Result.from_values("SpaceConsistencyBear", "Trailing whitespace found", file="file", line=5), Result.from_values("SpaceConsistencyBear", "Trailing whitespace found", file="file", line=2)], {abspath("file"): ["test line\n", "\t\n", "line 3\n", "line 4\n", "line 5\t\n"]}, {}, color=False) self.assertEqual(""" file | 2| {0} | | [NORMAL] SpaceConsistencyBear: | | {1} file | 5| {2} | | [NORMAL] SpaceConsistencyBear: | | {1}\n""".format(highlight_text('\t', self.lexer), highlight_text("Trailing whitespace found", style=BackgroundMessageStyle), highlight_text('line 5\t', self.lexer)), stdout.getvalue()) def test_print_results_multiple_ranges(self): affected_code = ( SourceRange.from_values("some_file", 5, end_line=7), SourceRange.from_values("another_file", 1, 3, 1, 5), SourceRange.from_values("another_file", 3, 3, 3, 5)) with retrieve_stdout() as stdout: print_results( self.log_printer, Section(""), [Result("ClangCloneDetectionBear", "Clone Found", affected_code)], {abspath("some_file"): ["line " + str(i + 1) + "\n" for i in range(10)], abspath("another_file"): ["line " + str(i + 1) for i in range(10)]}, {}, color=False) self.assertEqual(""" another_file | 1| li{0}{1} another_file | 3| li{0}{2} some_file | 5| {3} | 6| {4} | 7| {5} | | [NORMAL] ClangCloneDetectionBear: | | {6}\n""".format(highlight_text('ne', self.lexer, BackgroundSourceRangeStyle), highlight_text(' 1', self.lexer), highlight_text(' 3', self.lexer), highlight_text('line 5', self.lexer), highlight_text('line 6', self.lexer), highlight_text('line 7', self.lexer), highlight_text("Clone Found", style=BackgroundMessageStyle)), stdout.getvalue()) def test_print_results_missing_file(self): self.log_printer = LogPrinter(NullPrinter()) with retrieve_stdout() as stdout: print_results( self.log_printer, Section(""), [Result("t", "msg"), Result.from_values("t", "msg", file="file", line=5)], {}, {}, color=False) self.assertEqual("\n" + STR_PROJECT_WIDE + "\n" "| | [NORMAL] t:\n" "| | {0}\n" # Second results file isn't there, no context is # printed, only a warning log message which we # don't catch "| | [NORMAL] t:\n" "| | {0}\n".format( highlight_text("msg", style=BackgroundMessageStyle)), stdout.getvalue()) def test_print_results_missing_line(self): with retrieve_stdout() as stdout: print_results( self.log_printer, Section(""), [Result.from_values("t", "msg", file="file", line=5), Result.from_values("t", "msg", file="file", line=6)], {abspath("file"): ["line " + str(i + 1) for i in range(5)]}, {}, color=False) self.assertEqual("\n" "file\n" "| 5| {0}\n" "| | [NORMAL] t:\n" "| | {1}\n" "\n" "file\n" "| 6| {2}\n" "| | [NORMAL] t:\n" "| | {1}\n".format( highlight_text('line 5', self.lexer), highlight_text("msg", style=BackgroundMessageStyle), STR_LINE_DOESNT_EXIST), stdout.getvalue()) def test_print_results_without_line(self): with retrieve_stdout() as stdout: print_results( self.log_printer, Section(""), [Result.from_values("t", "msg", file="file")], {abspath("file"): []}, {}, color=False) self.assertEqual( "\nfile\n" "| | [NORMAL] t:\n" "| | {}\n".format(highlight_text( "msg", style=BackgroundMessageStyle)), stdout.getvalue())