Gentoo Archives: gentoo-portage-dev

From: Mike Frysinger <vapier@g.o>
To: gentoo-portage-dev@l.g.o
Subject: [gentoo-portage-dev] [RFC/PATCH] repoman: unroll escaped lines so we can check the entirety of it
Date: Thu, 24 May 2012 06:14:40
Message-Id: 1337832399-14375-1-git-send-email-vapier@gentoo.org
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 This seems to work, but maybe someone can suggest something simpler.
7
8 Signed-off-by: Mike Frysinger <vapier@g.o>
9 ---
10 pym/repoman/checks.py | 35 +++++++++++++++++++++++++++++++++++
11 1 files changed, 35 insertions(+), 0 deletions(-)
12
13 diff --git a/pym/repoman/checks.py b/pym/repoman/checks.py
14 index 65e7136..67f2b0a 100644
15 --- a/pym/repoman/checks.py
16 +++ b/pym/repoman/checks.py
17 @@ -750,11 +750,46 @@ _ignore_comment_re = re.compile(r'^\s*#')
18 def run_checks(contents, pkg):
19 checks = _constant_checks
20 here_doc_delim = None
21 + multiline = None
22
23 for lc in checks:
24 lc.new(pkg)
25 for num, line in enumerate(contents):
26
27 + # Unroll multiline escaped strings so that we can check things:
28 + # inherit foo bar \
29 + # moo \
30 + # cow
31 + # This will merge these lines like so:
32 + # inherit foo bar moo cow
33 + try:
34 + # A normal line will end in the two bytes: <\> <\n>. So decoding
35 + # that will result in python thinking the <\n> is being escaped
36 + # and eat the single <\> which makes it hard for us to detect.
37 + # Instead, strip the newline (which we know all lines have), and
38 + # append a <0>. Then when python escapes it, if the line ended
39 + # in a <\>, we'll end up with a <\0> marker to key off of. This
40 + # shouldn't be a problem with any valid ebuild ...
41 + line_escaped = (line.rstrip('\n') + '0').decode('string_escape')
42 + except:
43 + # Who knows what kind of crazy crap an ebuild will have
44 + # in it -- don't allow it to kill us.
45 + line_escaped = line
46 + if multiline:
47 + # Chop off the \ and \n bytes from the previous line.
48 + multiline = multiline[:-2] + line
49 + if not line_escaped.endswith('\0'):
50 + line = multiline
51 + num = multinum
52 + multiline = None
53 + else:
54 + continue
55 + else:
56 + if line_escaped.endswith('\0'):
57 + multinum = num
58 + multiline = line
59 + continue
60 +
61 # Check if we're inside a here-document.
62 if here_doc_delim is not None:
63 if here_doc_delim.match(line):
64 --
65 1.7.8.6

Replies