1 |
commit: 9ec7e9fd222849e1fbe6311bb6973867957a9d81 |
2 |
Author: Zac Medico <zmedico <AT> gentoo <DOT> org> |
3 |
AuthorDate: Wed Dec 21 22:58:41 2011 +0000 |
4 |
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Dec 21 22:58:41 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=9ec7e9fd |
7 |
|
8 |
vardbapi.aux_get: search environment, bug 395463 |
9 |
|
10 |
--- |
11 |
pym/portage/dbapi/vartree.py | 84 +++++++++++++++++++++++++++++++++++++++-- |
12 |
1 files changed, 79 insertions(+), 5 deletions(-) |
13 |
|
14 |
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py |
15 |
index 6e71848..6f8ee5f 100644 |
16 |
--- a/pym/portage/dbapi/vartree.py |
17 |
+++ b/pym/portage/dbapi/vartree.py |
18 |
@@ -32,6 +32,7 @@ portage.proxy.lazyimport.lazyimport(globals(), |
19 |
'portage.util._dyn_libs.LinkageMapELF:LinkageMapELF@LinkageMap', |
20 |
'portage.versions:best,catpkgsplit,catsplit,cpv_getkey,pkgcmp,' + \ |
21 |
'_pkgsplit@pkgsplit', |
22 |
+ 'subprocess', |
23 |
'tarfile', |
24 |
) |
25 |
|
26 |
@@ -717,18 +718,91 @@ class vardbapi(dbapi): |
27 |
myd = myf.read() |
28 |
finally: |
29 |
myf.close() |
30 |
- # Preserve \n for metadata that is known to |
31 |
- # contain multiple lines. |
32 |
- if self._aux_multi_line_re.match(x) is None: |
33 |
- myd = " ".join(myd.split()) |
34 |
except IOError: |
35 |
- myd = _unicode_decode('') |
36 |
+ myd = None |
37 |
+ if x not in self._aux_cache_keys: |
38 |
+ myd = self._aux_env_search(mycpv, x) |
39 |
+ if myd is None: |
40 |
+ myd = _unicode_decode('') |
41 |
+ |
42 |
+ # Preserve \n for metadata that is known to |
43 |
+ # contain multiple lines. |
44 |
+ if self._aux_multi_line_re.match(x) is None: |
45 |
+ myd = " ".join(myd.split()) |
46 |
+ |
47 |
if x == "EAPI" and not myd: |
48 |
results.append(_unicode_decode('0')) |
49 |
else: |
50 |
results.append(myd) |
51 |
return results |
52 |
|
53 |
+ def _aux_env_search(self, cpv, variable): |
54 |
+ """ |
55 |
+ Search environment.bz2 of the specified variable. Returns |
56 |
+ the value if found, otherwise None. This is useful for |
57 |
+ querying variables like ${SRC_URI} and ${A}, which are not |
58 |
+ saved in separate files but are available in environment.bz2 |
59 |
+ (see bug #395463). |
60 |
+ """ |
61 |
+ env_file = self.getpath(cpv, filename="environment.bz2") |
62 |
+ if not os.path.isfile(env_file): |
63 |
+ return None |
64 |
+ bunzip2_cmd = portage.util.shlex_split( |
65 |
+ self.settings.get("PORTAGE_BUNZIP2_COMMAND", "")) |
66 |
+ if not bunzip2_cmd: |
67 |
+ bunzip2_cmd = portage.util.shlex_split( |
68 |
+ self.settings["PORTAGE_BZIP2_COMMAND"]) |
69 |
+ bunzip2_cmd.append("-d") |
70 |
+ args = bunzip2_cmd + ["-c", env_file] |
71 |
+ try: |
72 |
+ proc = subprocess.Popen(args, stdout=subprocess.PIPE) |
73 |
+ except EnvironmentError as e: |
74 |
+ if e.errno != errno.ENOENT: |
75 |
+ raise |
76 |
+ raise portage.exception.CommandNotFound(args[0]) |
77 |
+ |
78 |
+ # Parts of the following code are borrowed from |
79 |
+ # filter-bash-environment.py (keep them in sync). |
80 |
+ var_assign_re = re.compile(r'(^|^declare\s+-\S+\s+|^declare\s+|^export\s+)([^=\s]+)=("|\')?(.*)$') |
81 |
+ close_quote_re = re.compile(r'(\\"|"|\')\s*$') |
82 |
+ def have_end_quote(quote, line): |
83 |
+ close_quote_match = close_quote_re.search(line) |
84 |
+ return close_quote_match is not None and \ |
85 |
+ close_quote_match.group(1) == quote |
86 |
+ |
87 |
+ value = None |
88 |
+ for line in proc.stdout: |
89 |
+ line = _unicode_decode(line, |
90 |
+ encoding=_encodings['content'], errors='replace') |
91 |
+ var_assign_match = var_assign_re.match(line) |
92 |
+ if var_assign_match is not None: |
93 |
+ if var_assign_match.group(2) == variable: |
94 |
+ quote = var_assign_match.group(3) |
95 |
+ if quote is not None: |
96 |
+ if have_end_quote(quote, |
97 |
+ line[var_assign_match.end(2)+2:]): |
98 |
+ value = var_assign_match.group(4) |
99 |
+ else: |
100 |
+ value = [var_assign_match.group(4)] |
101 |
+ for line in proc.stdout: |
102 |
+ value.append(line) |
103 |
+ if have_end_quote(quote, line): |
104 |
+ break |
105 |
+ value = ''.join(value) |
106 |
+ # remove trailing quote and whitespace |
107 |
+ value = value.rstrip()[:-1] |
108 |
+ else: |
109 |
+ value = var_assign_match.group(4).rstrip() |
110 |
+ |
111 |
+ # ignore remainder of file |
112 |
+ for line in proc.stdout: |
113 |
+ pass |
114 |
+ break |
115 |
+ |
116 |
+ proc.wait() |
117 |
+ proc.stdout.close() |
118 |
+ return value |
119 |
+ |
120 |
def aux_update(self, cpv, values): |
121 |
mylink = self._dblink(cpv) |
122 |
if not mylink.exists(): |