Gentoo Archives: gentoo-portage-dev

From: Mike Frysinger <vapier@g.o>
To: gentoo-portage-dev@l.g.o
Subject: [gentoo-portage-dev] [PATCH v2] repoman: unroll escaped lines so we can check the entirety of it
Date: Thu, 24 May 2012 21:15:43
Message-Id: 1337887224-29136-1-git-send-email-vapier@gentoo.org
In Reply to: [gentoo-portage-dev] [RFC/PATCH] repoman: unroll escaped lines so we can check the entirety of it by Mike Frysinger
1 Sometimes people wrap long lines in their ebuilds to make it easier to
2 read, but this causes us issues when doing line-by-line checking. So
3 automatically unroll those lines before passing the full content down
4 to our checkers.
5
6 Signed-off-by: Mike Frysinger <vapier@g.o>
7 ---
8 v2
9 - re-order heredoc/multiline checking
10
11 pym/repoman/checks.py | 60 +++++++++++++++++++++++++++++++++++++++---------
12 1 files changed, 48 insertions(+), 12 deletions(-)
13
14 diff --git a/pym/repoman/checks.py b/pym/repoman/checks.py
15 index c17a0bd..cd8d3d2 100644
16 --- a/pym/repoman/checks.py
17 +++ b/pym/repoman/checks.py
18 @@ -759,6 +759,7 @@ _ignore_comment_re = re.compile(r'^\s*#')
19 def run_checks(contents, pkg):
20 checks = _constant_checks
21 here_doc_delim = None
22 + multiline = None
23
24 for lc in checks:
25 lc.new(pkg)
26 @@ -772,19 +773,54 @@ def run_checks(contents, pkg):
27 here_doc = _here_doc_re.match(line)
28 if here_doc is not None:
29 here_doc_delim = re.compile(r'^\s*%s$' % here_doc.group(1))
30 + if here_doc_delim is not None:
31 + continue
32 +
33 + # Unroll multiline escaped strings so that we can check things:
34 + # inherit foo bar \
35 + # moo \
36 + # cow
37 + # This will merge these lines like so:
38 + # inherit foo bar moo cow
39 + try:
40 + # A normal line will end in the two bytes: <\> <\n>. So decoding
41 + # that will result in python thinking the <\n> is being escaped
42 + # and eat the single <\> which makes it hard for us to detect.
43 + # Instead, strip the newline (which we know all lines have), and
44 + # append a <0>. Then when python escapes it, if the line ended
45 + # in a <\>, we'll end up with a <\0> marker to key off of. This
46 + # shouldn't be a problem with any valid ebuild ...
47 + line_escaped = (line.rstrip('\n') + '0').decode('string_escape')
48 + except:
49 + # Who knows what kind of crazy crap an ebuild will have
50 + # in it -- don't allow it to kill us.
51 + line_escaped = line
52 + if multiline:
53 + # Chop off the \ and \n bytes from the previous line.
54 + multiline = multiline[:-2] + line
55 + if not line_escaped.endswith('\0'):
56 + line = multiline
57 + num = multinum
58 + multiline = None
59 + else:
60 + continue
61 + else:
62 + if line_escaped.endswith('\0'):
63 + multinum = num
64 + multiline = line
65 + continue
66
67 - if here_doc_delim is None:
68 - # We're not in a here-document.
69 - is_comment = _ignore_comment_re.match(line) is not None
70 - for lc in checks:
71 - if is_comment and lc.ignore_comment:
72 - continue
73 - if lc.check_eapi(pkg.metadata['EAPI']):
74 - ignore = lc.ignore_line
75 - if not ignore or not ignore.match(line):
76 - e = lc.check(num, line)
77 - if e:
78 - yield lc.repoman_check_name, e % (num + 1)
79 + # Finally we have a full line to parse.
80 + is_comment = _ignore_comment_re.match(line) is not None
81 + for lc in checks:
82 + if is_comment and lc.ignore_comment:
83 + continue
84 + if lc.check_eapi(pkg.metadata['EAPI']):
85 + ignore = lc.ignore_line
86 + if not ignore or not ignore.match(line):
87 + e = lc.check(num, line)
88 + if e:
89 + yield lc.repoman_check_name, e % (num + 1)
90
91 for lc in checks:
92 i = lc.end()
93 --
94 1.7.8.6

Replies