예제 #1
0
 def prepare(self):
     super(Patch, self).prepare()
     self.package = self.kwds['package']
     self.subpackage_of = self.kwds.get('subpackage_of')
     self.patch = self.kwds['patch']
     self.branch = self.kwds['branch']
     if self.subpackage_of:
         main_package = self.subpackage_of
     else:
         main_package = self.package
     repo = FedoraGitRepo(main_package, branch=self.branch)
     diff = repo.get_patch(self.patch)
     if self.diffstat:
         self.diffstat = repo.get_diffstat(self.patch)
     self.text = highlight(diff, DiffLexer(),
                           HtmlFormatter(full=True, nobackground=True))
     self.changelog = repo.get_patch_changelog(self.patch)
예제 #2
0
    def get_context_data(self, *args, **kwargs):
        deploy_id = kwargs['deploy']
        context = super(DeployInfo, self).get_context_data(*args, **kwargs)

        url = '{}/deploys/{}'.format(settings.TSURU_HOST, deploy_id)
        response = requests.get(url, headers=self.authorization)
        context['deploy'] = response.json()

        diff = context['deploy'].get('Diff')
        if diff and diff != u'The deployment must have at least two commits for the diff.':
            format = HtmlFormatter()
            diff = highlight(diff, DiffLexer(), format)
        else:
            diff = None

        context['deploy']['Diff'] = diff
        return context
예제 #3
0
def print_diff(path: Path, old: TextDocument, new: TextDocument) -> None:
    """Print ``black --diff`` style output for the changes"""
    relative_path = path.resolve().relative_to(Path.cwd()).as_posix()
    diff = "\n".join(
        line.rstrip("\n") for line in unified_diff(
            old.lines, new.lines, relative_path, relative_path))

    if sys.stdout.isatty():
        try:
            from pygments import highlight
            from pygments.formatters import TerminalFormatter
            from pygments.lexers import DiffLexer
        except ImportError:
            print(diff)
        else:
            print(highlight(diff, DiffLexer(), TerminalFormatter()))
    else:
        print(diff)
예제 #4
0
    def _style_diff(self, diff):
        """Return a syntax-highlighted version of the diff.

        Args:
            diff (bytes):
                The raw diff content.

        Returns:
            django.utils.safestring.SafeText:
            The syntax-highlighted HTML.
        """
        # NOTE: Django wraps the contents in a <p>, but browsers will
        #       be sad about that, because it contains a <pre>. Chrome,
        #       for instance, will move it out into its own node. Be
        #       consistent and just make that happen for them.
        return format_html(
            '</p>{0}<p>',
            mark_safe(highlight(diff, DiffLexer(), HtmlFormatter())))
예제 #5
0
def diffmenu(outputfile, diffout):

    print "[Continue, Abort, View, Replace?] ",
    response = sys.stdin.readline()
    rchar = response[0].upper()

    if rchar == 'C':
        return
    elif rchar == 'A':
        sys.exit(-1)
    elif rchar == 'V':
        print highlight(diffout, DiffLexer(), TerminalFormatter(bg="dark"))
        diffmenu(outputfile, diffout)
    elif rchar == 'R':
        dest = 'expected/' + outputfile
        copy(outputfile, dest)
    else:
        print "Please enter a valid option: ",
        diffmenu(sourcefile, diffout)
예제 #6
0
 def view_diff(self, request, object_id, mode="u", r1=None, r2=None):
     """
     ##
     ## Render diff form
     ##
     :param request:
     :param object_id:
     :param mode:
     :param r1:
     :param r2:
     :return:
     """
     o = get_object_or_404(Object.get_object_class(self.repo),
                           id=int(object_id))
     if not o.has_access(request.user):
         return self.response_forbidden("Access denied")
     if request.POST:
         r1 = request.POST.get("r1", r1)
         r2 = request.POST.get("r2", r2)
     if r1 and r2:
         rev1 = o.find_revision(r1)
         rev2 = o.find_revision(r2)
         if mode == "2":
             d1 = o.get_revision(rev1)
             d2 = o.get_revision(rev2)
             d = difflib.HtmlDiff()
             diff = d.make_table(d1.splitlines(), d2.splitlines())
             diff = diff.replace("rules=\"groups\"", "rules=\"none\"",
                                 1)  # Use no colgroup rules
         else:
             diff = o.diff(rev1, rev2)
             diff = unicode(diff, "utf8")
             diff = highlight(diff, DiffLexer(),
                              NOCHtmlFormatter())  # Highlight diff
         return self.render(request, "diff.html", {
             "o": o,
             "diff": diff,
             "r1": r1,
             "r2": r2,
             "mode": mode
         })
     else:
         return self.response_redirect_to_object(o)
예제 #7
0
def get_diff_html(snapshots):

    html = ''
    for new, old in zip(snapshots, snapshots[1:]):
        old_date = '{} ({})'.format(old[0].replace(microsecond=0),
                                    humanize.naturaltime(old[0]))
        new_date = '{} ({})'.format(new[0].replace(microsecond=0),
                                    humanize.naturaltime(new[0]))
        diff_text = '\n'.join(
            difflib.unified_diff(
                old[1],
                new[1],
                fromfiledate=old_date,
                tofiledate=new_date,
                n=5,
                lineterm='',
            ))
        html += highlight(diff_text, DiffLexer(), HtmlFormatter())

    return html
예제 #8
0
    def get_context_data(self, **kwargs):
        deploy_id = kwargs["deploy"]

        url = "{}/deploys/{}".format(settings.TSURU_HOST, deploy_id)
        response = requests.get(url, headers=self.authorization)

        if response.status_code > 399:
            raise Http404("Deploy does not exist")

        context = {"deploy": response.json()}

        diff = context["deploy"].get("Diff")
        if diff and diff != u'The deployment must have at least two commits for the diff.':
            format = HtmlFormatter()
            diff = highlight(diff, DiffLexer(), format)
        else:
            diff = None

        context["deploy"]["Diff"] = diff
        return context
예제 #9
0
파일: compare.py 프로젝트: syntaxaire/site
    def get(self, first_rev, second_rev):
        before = self.db.get(self.table_name, first_rev)
        after = self.db.get(self.table_name, second_rev)

        if not (before and after):
            raise NotFound()

        if before["date"] > after[
                "date"]:  # Check whether the before was created after the after
            raise BadRequest()

        if before["id"] == after["id"]:  # The same revision has been requested
            raise BadRequest()

        before_text = before["post"]["rst"]
        after_text = after["post"]["rst"]

        if not before_text.endswith("\n"):
            before_text += "\n"

        if not after_text.endswith("\n"):
            after_text += "\n"

        before_text = before_text.splitlines(keepends=True)
        after_text = after_text.splitlines(keepends=True)

        if not before["slug"] == after["slug"]:
            raise BadRequest()  # The revisions are not from the same post

        diff = difflib.unified_diff(before_text,
                                    after_text,
                                    fromfile=f"{first_rev}.rst",
                                    tofile=f"{second_rev}.rst")
        diff = "".join(diff)
        diff = highlight(diff, DiffLexer(), HtmlFormatter())
        return self.render("wiki/compare_revision.html",
                           title=after["post"]["title"],
                           page=before["slug"],
                           diff=diff,
                           slug=before["slug"],
                           can_edit=self.is_staff())
예제 #10
0
def _handle_metadata_post(request, form, return_view):
    if form.is_valid():
        if request.is_ajax():
            # validation of metadata and diff calculation
            diff = form.get_diff()
            html = highlight(diff, DiffLexer(), HtmlFormatter(linenos=True))
            return HttpResponse(html.encode(settings.DEFAULT_CHARSET))
        else:
            # after validation and when user has added the commit message
            if 'button_clicked' in request.POST and request.POST[
                    'button_clicked'] != '':
                action = request.POST['button_clicked']
            else:
                action = None
            form.save(action)
            messages.success(request, _get_success_message(action))
            return_url = reverse(return_view, args=(form.entity.id, ))
            return HttpResponseRedirect(return_url)
    else:
        messages.error(request, _('Please correct the errors indicated below'))
        if request.is_ajax():
            sorted_errors = {}
            for field, errors in form.errors.items():
                sorted_error_list = []
                for error in errors:
                    if ':ERROR:' in error or ':FATAL:' in error:
                        sorted_error_list.insert(0, error)
                    else:
                        sorted_error_list.append(error)
                sorted_errors[field] = sorted_error_list

            content = render_to_string(
                'entity/validation_errors.html', {
                    'errors': sorted_errors,
                },
                context_instance=RequestContext(request))
            return HttpResponseBadRequest(content)
예제 #11
0
def diff_to_html(diff_text):
    html = HtmlFormatter()
    return highlight(diff_text, DiffLexer(),
                     html) + "<style>%s</style" % html.get_style_defs()
예제 #12
0
 def _style_diff(self, diff):
     # NOTE: Django wraps the contents in a <p>, but browsers will
     #       be sad about that, because it contains a <pre>. Chrome,
     #       for instance, will move it out into its own node. Be
     #       consistent and just make that happen for them.
     return '</p>%s<p>' % highlight(diff, DiffLexer(), HtmlFormatter())
예제 #13
0
def main(appliances=[],
         credentials=[],
         timeout=120,
         no_check_hostname=False,
         base_dir=default_base_dir,
         comment=default_comment,
         page=False,
         no_highlight_diff=False):
    """
    track_autoconfig.py

    Description:

    Store persisted domain configuration in a local git repository
    for auditing purposes.

    Usage:

        :::bash
        $ mast contrib/track_autoconfig.py --appliances <HOSTNAMES> --credentials <USER:PASS> --base-dir tmp/config

    Parameters:

    * `-a, --appliances` - The hostname(s), ip addresse(s), environment name(s)
    or alias(es) of the appliances you would like to affect. For details
    on configuring environments please see the comments in
    `environments.conf` located in `$MAST_HOME/etc/default`. For details
    on configuring aliases please see the comments in `hosts.conf` located
    in `$MAST_HOME/etc/default`.
    * `-c, --credentials`: The credentials to use for authenticating to the
    appliances. Should be either one set to use for all appliances
    or one set for each appliance. Credentials should be in the form
    `username:password` and should be provided in a space-seperated list
    if multiple are provided. If you would prefer to not use plain-text
    passwords, you can use the output of
    `$ mast-system xor <username:password>`.
    * `-t, --timeout`: The timeout in seconds to wait for a response from
    an appliance for any single request. __NOTE__ Program execution may
    halt if a timeout is reached.
    * `-n, --no-check-hostname`: If specified SSL verification will be turned
    off when sending commands to the appliances.
    * `-b, --base-dir`: The base directory where to store the downloaded
    files. Files will actually be stored in a subdirectory of `base_dir`
    named after the hostname in the form of `base_dir/<hostname>`
    * `-p, --page`: If specified, page the output when too long to display
    at once
    * `-N, --no-highlight-diff`: If specified, the output of the diff will
    be syntax-highlighted
    """
    base_dir = os.path.abspath(base_dir)
    if not os.path.exists(base_dir):
        os.makedirs(base_dir)
    try:
        repo = git.Repo(base_dir)
        first_sha1 = repo.head()
        print first_sha1
    except NotGitRepository:
        print "Initializing git repository"
        git.init(base_dir)
        git.add(base_dir)
        first_sha1 = git.commit(base_dir, message="Initial Commit")
        print first_sha1
    except KeyError:
        git.add(base_dir)
        git.commit(base_dir, message="Initial Commit")
    print
    pull_autoconfig(appliances=appliances,
                    credentials=credentials,
                    timeout=timeout,
                    no_check_hostname=no_check_hostname,
                    base_dir=base_dir)
    git.add(base_dir)
    print git.status(base_dir)
    second_sha1 = git.commit(base_dir, message=comment)
    print second_sha1
    print "\n\nDIFF\n\n"

    tmp = StringIO()
    git.show(base_dir, outstream=tmp)
    tmp.seek(0)

    if no_highlight_diff:
        out = tmp.read()
    else:
        out = highlight(tmp.read(), DiffLexer(), TerminalFormatter())

    if page:
        pprint.page(out)
    else:
        print out
예제 #14
0
def main():
    import argparse

    parser = argparse.ArgumentParser(
        description="reformat the docstrigns of some file")
    parser.add_argument("files",
                        metavar="files",
                        type=str,
                        nargs="+",
                        help="TODO")
    parser.add_argument("--context", metavar="context", type=int, default=3)
    parser.add_argument("--write",
                        dest="write",
                        action="store_true",
                        help="print the diff")

    args = parser.parse_args()
    for file in args.files:
        #print(file)
        with open(file, "r") as f:
            data = f.read()

        tree = ast.parse(data)
        new = data

        funcs = [t for t in tree.body if isinstance(t, ast.FunctionDef)]
        for i, func in enumerate(funcs[:]):
            # print(i, "==", func.name, "==")
            try:
                docstring = func.body[0].value.s
            except AttributeError:
                continue
            if not isinstance(docstring, str):
                continue
            start, nindent, stop = (
                func.body[0].lineno,
                func.body[0].col_offset,
                func.body[0].end_lineno,
            )
            if not docstring in data:
                print(f"skip {file}: {func.name}, can't do replacement yet")

            new_doc = compute_new_doc(docstring, file)
            # test(docstring, file)
            if new_doc:
                if ('"""' in new_doc) or ("'''" in new_doc):
                    print("SKIPPING", file, func.name,
                          "triple quote not handled", new_doc)
                else:
                    new = new.replace(docstring, new_doc)

            # test(docstring, file)
        if new != data:
            dold = data.splitlines()
            dnew = new.splitlines()
            diffs = list(
                difflib.unified_diff(dold,
                                     dnew,
                                     n=args.context,
                                     fromfile=file,
                                     tofile=file), )
            from pygments import highlight
            from pygments.lexers import DiffLexer
            from pygments.formatters import TerminalFormatter

            if not args.write:
                code = "\n".join(diffs)
                hldiff = highlight(code, DiffLexer(), TerminalFormatter())

                print(hldiff)
            else:
                with open(file, "w") as f:
                    f.write(new)
예제 #15
0
    fd = os.path.realpath(curdir)
    if os.path.isfile(fd):
        prog = fd
        curdir = os.path.dirname(prog)
    elif not (prog := guess_program(fd)):
        return [], [(f"Cannot guess program from {curdir}", [])]
    if not (tests := guess_tests(fd)):
        return [], [(f"Cannot guess tests from {curdir}", [])]

    passed, failed = suite(prog, tests)
    if failed:
        for name, diff in failed:
            print(f"\t### {bname(name)} ###")
            if all((os.isatty(1), highlight, DiffLexer, TerminalFormatter)):
                print(
                    highlight("".join(diff), DiffLexer(), TerminalFormatter()))
            else:
                sys.stdout.writelines(diff)
            print()
    return passed, failed


if __name__ == "__main__":
    cwd = os.getcwd()
    ex = 0

    wait = "-" in sys.argv
    if wait:
        sys.argv.remove("-")

    if len(sys.argv) < 2:
예제 #16
0
def pygmentize_diff(value):
    return mark_safe(highlight(value, DiffLexer(), HtmlFormatter()))
예제 #17
0
 def _highlight(diff):
     return pygments.highlight(diff, DiffLexer(), html_formatter)
예제 #18
0
파일: models.py 프로젝트: heschlie/dewey
 def diff(self):
     if self.change_type == 'diff':
         content = self.content.replace('\\n', '\n')
         return highlight(
             content, DiffLexer(),
             HtmlFormatter(cssclass='code highlight', noclasses=True))
예제 #19
0
    def finished(self):
        from pygments.lexers import (PythonTracebackLexer, PythonLexer,
                                     DiffLexer)
        if ANSI_COLORS_SUPPORT:
            from pygments.console import colorize
            from pygments import highlight

            if self.style in ('light', 'dark'):
                from pygments.formatters import TerminalFormatter
                formatter = TerminalFormatter(bg=self.style)
                if self.colorscheme is not None:
                    from pygments.token import string_to_tokentype
                    for token, value in self.colorscheme.iteritems():
                        token = string_to_tokentype(token.capitalize())
                        formatter.colorscheme[token] = (value, value)
            else:
                from pygments.formatters import Terminal256Formatter
                formatter = Terminal256Formatter(style=self.style)
        else:
            # ANSI color codes seem not to be supported, make colorize()
            # and highlight() no-ops.
            formatter = None

            def colorize(_format, text):
                return text

            def highlight(text, _lexer, _formatter):
                return text

        if self.counter:
            self.progress.finish()
        print

        width, _ = utils.get_terminal_size()

        def show(result):
            print colorize('bold', result.test_name)
            if result.test.__doc__:
                print inspect.getdoc(result.test)
            print colorize('faint', '─' * width)
            for line in result.stdout:
                print colorize('bold', '→'),
                print line
            for line in result.stderr:
                print colorize('red', '→'),
                print line

        if self.verbose:
            for result in self.passes:
                if result.stdout or result.stderr:
                    show(result)
                    print

        for result in self.failures:
            show(result)

            # result.traceback seems to be in UTF-8 on my system (eg. for
            # literal unicode strings) but I guess this depends on the source
            # file encoding. Tell Pygments to guess: try UTF-8 and then latin1.
            # Without an `encoding` argument, Pygments just uses latin1.
            print highlight(result.traceback,
                            PythonTracebackLexer(encoding='guess'), formatter)

            assertion = result.assertion
            if assertion is not None:
                print highlight(assertion, PythonLexer(encoding='guess'),
                                formatter)

            equality_diff = result.equality_diff
            if equality_diff is not None:
                print highlight(equality_diff, DiffLexer(encoding='guess'),
                                formatter)

            result.debug()

        if self.failures:
            failed = colorize('red', str(len(self.failures)))
        else:
            failed = len(self.failures)
        print 'Failures: %s/%s (%s assertions, %.3f seconds)' % (
            failed, self.counter, statistics.assertions, self.total_time)

        if self.failures:
            raise SystemExit(1)
예제 #20
0
 def set_diff(self, diff):
     data = highlight(diff, DiffLexer(), HtmlFormatter(noclasses=True))
     self._html.display_html(data)
예제 #21
0
def main(appliances=[],
         credentials=[],
         timeout=120,
         no_check_hostname=False,
         base_dir=default_base_dir,
         comment=default_comment,
         persisted=False,
         recursive=False,
         no_strip_timestamp=False,
         page=False):
    """
    track_getconfig.py

    Description:

    Store running or persisted domain configuration in a local git
    repository for auditing purposes.

    Usage:

        :::bash
        $ mast contrib/track_getconfig.py --appliances <HOSTNAMES> --credentials <USER:PASS> --base-dir tmp/config

    Parameters:

    * `-a, --appliances` - The hostname(s), ip addresse(s), environment name(s)
    or alias(es) of the appliances you would like to affect. For details
    on configuring environments please see the comments in
    `environments.conf` located in `$MAST_HOME/etc/default`. For details
    on configuring aliases please see the comments in `hosts.conf` located
    in `$MAST_HOME/etc/default`.
    * `-c, --credentials`: The credentials to use for authenticating to the
    appliances. Should be either one set to use for all appliances
    or one set for each appliance. Credentials should be in the form
    `username:password` and should be provided in a space-seperated list
    if multiple are provided. If you would prefer to not use plain-text
    passwords, you can use the output of
    `$ mast-system xor <username:password>`.
    * `-t, --timeout`: The timeout in seconds to wait for a response from
    an appliance for any single request. __NOTE__ Program execution may
    halt if a timeout is reached.
    * `-n, --no-check-hostname`: If specified SSL verification will be turned
    off when sending commands to the appliances.
    * `-b, --base-dir`: The base directory where to store the downloaded
    files. Files will actually be stored in a subdirectory of `base_dir`
    named after the hostname in the form of `base_dir/<hostname>`
    * `-p, --persisted`: If specified, the persisted configuration will
    be retrieved as opposed to the running configuration (which is the
    default)
    * `-r, --recursive`: If specified, the configuration will be retrieved
    recursively to the extent of the facilities provided by DataPower
    * `-N, --no-strip-timestamp`: If specified, the timestamp will not be
    stripped from the XML document, This is done because we are tracking
    this information with git and stripping this out allows us to alert
    on any changes in the repository as opposed to special-casing the
    difference in timestamp.
    * `-P, --page`: If specified, page the output when too long to display
    at once
    """
    base_dir = os.path.abspath(base_dir)
    if not os.path.exists(base_dir):
        os.makedirs(base_dir)
    try:
        repo = git.Repo(base_dir)
        repo.head()
    except NotGitRepository:
        print "Initializing git repository"
        git.init(base_dir)
        git.add(base_dir)
        git.commit(base_dir, message="Initial Commit")
    except KeyError:
        git.add(base_dir)
        git.commit(base_dir, message="Initial Commit")

    check_hostname = not no_check_hostname
    env = datapower.Environment(appliances,
                                credentials,
                                timeout=timeout,
                                check_hostname=check_hostname)

    for appliance in env.appliances:
        appliance_directory = os.path.join(base_dir, appliance.hostname)
        if not os.path.exists(appliance_directory):
            os.mkdir(appliance_directory)
        for domain in appliance.domains:
            config = appliance.get_config(domain=domain,
                                          recursive=recursive,
                                          persisted=persisted)

            config = config.pretty
            if no_strip_timestamp:
                pass
            else:
                config = re.sub(r"^.*?<dp:timestamp>.*?</dp:timestamp>.*?$",
                                r"",
                                config,
                                flags=re.MULTILINE)

            filename = os.path.join(appliance_directory,
                                    "{}.xml".format(domain))
            with open(filename, "wb") as fout:
                fout.write(config)

    git.add(base_dir)
    print git.status(base_dir)
    git.commit(base_dir, message=comment)

    tmp = StringIO()
    git.show(base_dir, outstream=tmp)
    tmp.seek(0)
    out = highlight(tmp.read(), DiffLexer(), TerminalFormatter())
    if page:
        pprint.page(out)
    else:
        print out
예제 #22
0
    def send_extra_emails(self):
        total = len(self.added_commits)

        for i, commit in enumerate(self.added_commits):
            if not commit.id in self.detailed_commits:
                continue

            if self.short_refname == 'master':
                branch = ""
            else:
                branch = "/" + self.short_refname

            total = len(self.added_commits)
            if total > 1 and self.needs_cover_email:
                count_string = ": %(index)s/%(total)s" % {
                    'index': i + 1,
                    'total': total
                }
            else:
                count_string = ""

            subject = "[%(projectshort)s%(branch)s%(count_string)s] [%(revision)s] %(subject)s" % {
                'projectshort':
                projectshort,
                'branch':
                branch,
                'count_string':
                count_string,
                'revision':
                git.rev_list('--all').count('\n') + 1 - (total - (i + 1)),
                'subject':
                commit.subject[0:SUBJECT_MAX_SUBJECT_CHARS]
            }

            # If there is a cover email, it has the X-Git-OldRev/X-Git-NewRev in it
            # for the total branch update. Without a cover email, we are conceptually
            # breaking up the update into individual updates for each commit
            #if self.needs_cover_email:
            #    self.generate_header(subject, include_revs=False, cc=[])
            #else:
            #    parent = git.rev_parse(commit.id + "^")
            #    self.generate_header(subject,
            #                         include_revs=True,
            #                         oldrev=parent, newrev=commit.id)
            body_summary = git.show(commit.id, M=True, stat=True)

            body =  body_summary + "\n" + \
                    git.show(commit.id, p=True, M=True, diff_filter="ACMRTUXB", pretty="format:---")
            if len(body) > MAX_DETAIL_BODY_SIZE:
                body = body_summary + "\n (The body has been shortened. Not all diffs are included) \n\n"

            html_body = None
            if len(body) < MAX_HTML_BODY_SIZE:
                try:
                    html_body = highlight(
                        body, DiffLexer(encoding='latin1'),
                        HtmlFormatter(encoding='latin1',
                                      full=True,
                                      noclasses=True,
                                      nobackground=True))
                except UnicodeDecodeError:
                    html_body = None

            self.mailer.send(subject, body, html_body)
예제 #23
0
def main():
    _config = ConfigParser()
    patterns = []
    if Path("setup.cfg").exists():
        _config.read("setup.cfg")
        patterns = [
            SkipPattern(x.strip())
            for x in _config.get("velin", "ignore_patterns", fallback="").split("\n")
            if x
        ]

    parser = argparse.ArgumentParser(description="reformat the docstrigns of some file")
    parser.add_argument(
        "paths",
        metavar="path",
        type=str,
        nargs="+",
        help="Files or folder to reformat",
    )
    parser.add_argument(
        "--context",
        metavar="context",
        type=int,
        default=3,
        help="Number of context lines in the diff",
    )
    parser.add_argument(
        "--unsafe",
        action="store_true",
        help="Lift some safety feature (don't fail if updating the docstring is not indempotent",
    )
    parser.add_argument(
        "--check",
        action="store_true",
        help="Print the list of files/lines number and exit with a non-0 exit status, Use it for CI.",
    )
    parser.add_argument(
        "--no-diff",
        action="store_false",
        dest="print_diff",
        help="Do not print the diff",
    )
    parser.add_argument(
        "--black",
        action="store_true",
        dest="run_black",
        help="Do not run black on examples",
    )
    parser.add_argument(
        "--with-placeholder",
        action="store_true",
        dest="with_placeholder",
        help="insert missing sections/parameters placehoders",
    )
    parser.add_argument("--no-color", action="store_false", dest="do_highlight")
    parser.add_argument("--compact", action="store_true", help="Please ignore")
    parser.add_argument("--no-fail", action="store_false", dest="fail")
    parser.add_argument(
        "--space-in-see-also-title", action="store_true", dest="space_in_see_also_title"
    )
    parser.add_argument(
        "--space-in-notes-title", action="store_true", dest="space_in_notes_title"
    )
    parser.add_argument(
        "--no-fixers",
        action="store_false",
        dest="run_fixers",
        help="try to only reformat and does not run fixers heuristics",
    )
    parser.add_argument(
        "--write",
        dest="write",
        action="store_true",
        help="Try to write the updated docstring to the files",
    )
    parser.add_argument(
        "--verbose",
        action="store_true",
        help="increase the verbosity of the output",
    )

    args = parser.parse_args()

    from types import SimpleNamespace

    config = Config(
        {
            "with_placeholder": args.with_placeholder,
            "compact_param": args.compact,
            "space_in_see_also_title": args.space_in_see_also_title,
            "space_in_notes_title": args.space_in_notes_title,
            "run_fixers": args.run_fixers,
        }
    )
    global BLACK_REFORMAT
    if args.run_black:
        BLACK_REFORMAT = True
    else:
        BLACK_REFORMAT = False

    global print
    if args.verbose:
        try:
            from there import print
        except ImportError:
            pass

    to_format = []

    for f in args.paths:
        p = Path(f)
        if p.is_dir():
            for sf in p.glob("**/*.py"):
                to_format.append(sf)
        else:
            to_format.append(p)

    def to_skip(file, patterns):
        for p in patterns:
            if re.match(p.file, file):
                if p.obj_pattern is None:
                    return True
                else:
                    return False
        return False

    need_changes = []
    for file in to_format:
        if to_skip(str(file), patterns):
            print("ignoring", file)
            continue

        try:
            with open(file) as f:
                data = f.read()
        except Exception as e:
            # continue
            continue
            raise RuntimeError(f"Fail reading {file}") from e

        obj_p = [p.obj_pattern for p in patterns if re.match(p.file, str(file))]
        new = reformat_file(
            data,
            file,
            args.compact,
            args.unsafe,
            fail=args.fail,
            config=config,
            obj_p=obj_p,
        )
        # test(docstring, file)
        if new != data:
            need_changes.append(str(file))

            dold = data.splitlines()
            dnew = new.splitlines()
            diffs = list(
                difflib.unified_diff(
                    dold, dnew, n=args.context, fromfile=str(file), tofile=str(file)
                ),
            )

            if args.print_diff and not args.write:
                code = "\n".join(diffs)

                if args.do_highlight:
                    from pygments import highlight
                    from pygments.formatters import TerminalFormatter
                    from pygments.lexers import DiffLexer

                    code = highlight(code, DiffLexer(), TerminalFormatter())

                print(code)
            if args.write:
                with open(file, "w") as f:
                    f.write(new)
    if args.check:
        if len(need_changes) != 0:
            sys.exit(
                "Some files/functions need updates:\n - " + "\n - ".join(need_changes)
            )
        else:
            sys.exit(0)
예제 #24
0
파일: git.py 프로젝트: yzou/openlibrary
 def diff(self, path):
     diff = self.system("git diff --ignore-space-at-eol " +
                        path).stdout.strip()
     html = highlight(diff, DiffLexer(),
                      HtmlFormatter(full=True, style="trac", nowrap=True))
     return web.storage(name=path, diff=diff, htmldiff=html)
예제 #25
0
        elif prop.tag == "code":  #and prop.text != "InvalidBinaryFile":
            ticketOut["code"] = prop.text
            if len(prop.text) < 1000:
                ticketOut["$$PATCH_SIZE$$"] = "%d bytes" % len(prop.text)
            else:
                ticketOut["$$PATCH_SIZE$$"] = "%.1f KB" % (len(prop.text) /
                                                           1024.0)
            if prop.text == "InvalidBinaryFile":
                ticketOut["$$PATCH$$"] = "<em>Patch is corrupt.</em>"
                ticketOut["$$PYGMENTS$$"] = ""
            else:
                hlCode = prop.text.replace("\t", "    ")
                if len(hlCode) > 5200:
                    hlCode = hlCode[:5000].rstrip(
                    ) + "\ndownload for full patch..."
                ticketOut["$$PATCH$$"] = highlight(hlCode, DiffLexer(
                ), HtmlFormatter()).replace(
                    '<pre', '<pre class="pre-scrollable"', 1).replace(
                        'download for full patch...',
                        '<em><strong>download for full patch...</strong></em>')
                ticketOut[
                    "$$PYGMENTS$$"] = '\n    <link rel="stylesheet" href="../pygments.css">'

    if "HISTORY" not in ticketOut:
        ticketOut["$$HISTORY$$"] = ""
        ticketOut["$$NUMBER_STAT$$"] = ticketOut["$$NUMBER$$"]
    else:
        ticketOut[
            "$$NUMBER_STAT$$"] = '<table style="width:100%%"><tr><td>%s</td><td class="text-right"><span class="badge">%d</span></td></tr></table>' % (
                ticketOut["$$NUMBER$$"], len(ticketOut["HISTORY"]))
    ticketsOut.append(ticketOut)
예제 #26
0
def makemail(entries, txtdiff):
    """
    Create an email definition suiting Amazon SES boto3 API.
    Args:
        entries:
        txtdiff: A piece of unified diff.

    Returns: Dictionary corresponding to message part of SES boto3 API.
    """
    from pygments import highlight
    from pygments.lexers import DiffLexer
    from pygments.formatters import HtmlFormatter

    loglines = []
    naughtyblock = ""
    pieces = []
    filediffs = ""
    hfmt = HtmlFormatter(style="rainbow_dash", noclasses=True)
    subjectline = "M-4 Yellow Alert!"

    for entry in entries:
        rev, ctime, author, committype, msg = entry[:5]
        if committype != "merge":
            ctime = ctime.strftime('%Y-%m-%d %H:%M:%S')
            arev = """<A href="https://github.com/theme-ontology/theming/commit/%s">%s..</A>""" % (rev, rev[:6])
            loglines.append("""<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>""" % (arev, ctime, author, msg))

    for line in txtdiff.split("\n"):
        match = re.match("^diff --git a/(.+?) b/(.+?)$", line)
        if match:
            pieces.append([])
        if pieces:
            pieces[-1].append(line.strip())
    for block in pieces:
        txt = '\n'.join(block)
        naughtylines = profanities(txt)
        filediffs += """\n%s""" % highlight(txt, DiffLexer(), hfmt)

    if naughtylines:
        if len(naughtylines) > 1:
            subjectline = "M-4 Double Red Alert!"
        else:
            subjectline = "M-4 Red Alert!"
        badlines = "\n".join(x[0] for x in naughtylines)
        badtypes, badexplain = [], []
        for _line, matches in naughtylines:
            badtypes.extend(x[2].capitalize() for x in matches)
            badexplain.extend((x[0], x[1]) for x in matches)
        badtypes = " and ".join(sorted(set(badtypes), reverse=True))
        badexplain = ', '.join('"%s" => "%s"' % x for x in sorted(set(badexplain)))
        naughtyblock = """
    <DIV style="background:#ff8888; padding: .1em .5em; margin: 1em 0em;">
        <H4>Potentially %s Language Detected in the Vicinity of M-4:</H4>
        <PRE>%s</PRE>
        <i style="font-size: xx-small;">%s</i>
    </DIV>
""" % (badtypes, badlines, badexplain)

    style = lib.email.ST_BASE + lib.email.ST_REAL_RAINBOW_DASH
    htmldiff = """
        <style>
        table.rainbow_dashtable {
        }
        %s
        </style>
        <DIV style="margin-bottom: 1em;">
            <H4><b>Your friendly M-4 Themeontolonic Assistant</b> detected changes in GIT.</H4>
            <P>Go to <A href="https://themeontology.org/">https://themeontology.org/</A> for more information.</P>
        </DIV>
        %s
        <TABLE class="motable">
        <tr>
            <th>rev</th>
            <th>utc</th>
            <th>author</th>
            <th>comment</th>
        </tr>
        %s
        </TABLE>
        %s
""" % (style, naughtyblock, "\n".join(loglines), filediffs)

    return {
        "Body": {
            "Html": {
                "Charset": "UTF-8",
                "Data": htmldiff,
            },
        },
        "Subject": {
            "Charset": "UTF-8",
            "Data": subjectline,
        },
    }