Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o
Cc: Zac Medico <zmedico@g.o>
Subject: [gentoo-portage-dev] [PATCH v3 1/2] dblink: case insensitive support for bug #524236
Date: Mon, 17 Nov 2014 20:29:56
Message-Id: 1416256178-18009-1-git-send-email-zmedico@gentoo.org
In Reply to: Re: [gentoo-portage-dev] [PATCH v2 1/2] dblink: case insensitive support for bug #524236 by Brian Dolbec
1 This adds a dblink._contents attribute with methods that provide
2 an interface for contents operations with "implicit" case handling.
3 The new methods are implemented in a separate
4 ContentsCaseSensitivityManager class, in order to avoid adding more
5 bloat to vartree.py.
6
7 X-Gentoo-Bug: 524236
8 X-Gentoo-Url: https://bugs.gentoo.org/show_bug.cgi?id=524236
9 ---
10 .../dbapi/_ContentsCaseSensitivityManager.py | 93 ++++++++++++++++++++++
11 pym/portage/dbapi/vartree.py | 3 +
12 2 files changed, 96 insertions(+)
13 create mode 100644 pym/portage/dbapi/_ContentsCaseSensitivityManager.py
14
15 diff --git a/pym/portage/dbapi/_ContentsCaseSensitivityManager.py b/pym/portage/dbapi/_ContentsCaseSensitivityManager.py
16 new file mode 100644
17 index 0000000..c479ec9
18 --- /dev/null
19 +++ b/pym/portage/dbapi/_ContentsCaseSensitivityManager.py
20 @@ -0,0 +1,93 @@
21 +# Copyright 2014 Gentoo Foundation
22 +# Distributed under the terms of the GNU General Public License v2
23 +
24 +class ContentsCaseSensitivityManager(object):
25 + """
26 + Implicitly handles case transformations that are needed for
27 + case-insensitive support.
28 + """
29 +
30 + def __init__(self, db):
31 + """
32 + @param db: A dblink instance
33 + @type db: vartree.dblink
34 + """
35 + self.getcontents = db.getcontents
36 +
37 + if "case-insensitive-fs" in db.settings.features:
38 + self.unmap_key = self._unmap_key_case_insensitive
39 + self.contains = self._contains_case_insensitive
40 + self.keys = self._keys_case_insensitive
41 +
42 + self._contents_insensitive = None
43 + self._reverse_key_map = None
44 +
45 + def clear_cache(self):
46 + """
47 + Clear all cached contents data.
48 + """
49 + self._contents_insensitive = None
50 + self._reverse_key_map = None
51 +
52 + def keys(self):
53 + """
54 + Iterate over all contents keys, which are transformed to
55 + lowercase when appropriate, for use in case-insensitive
56 + comparisons.
57 + @rtype: iterator
58 + @return: An iterator over all the contents keys
59 + """
60 + return iter(self.getcontents())
61 +
62 + def contains(self, key):
63 + """
64 + Check if the given key is contained in the contents, using
65 + case-insensitive comparison when appropriate.
66 + @param key: A filesystem path (including ROOT and EPREFIX)
67 + @type key: str
68 + @rtype: bool
69 + @return: True if the given key is contained in the contents,
70 + False otherwise
71 + """
72 + return key in self.getcontents()
73 +
74 + def unmap_key(self, key):
75 + """
76 + Map a key (from the keys method) back to its case-preserved
77 + form.
78 + @param key: A filesystem path (including ROOT and EPREFIX)
79 + @type key: str
80 + @rtype: str
81 + @return: The case-preserved form of key
82 + """
83 + return key
84 +
85 + def _case_insensitive_init(self):
86 + """
87 + Initialize data structures for case-insensitive support.
88 + """
89 + self._contents_insensitive = dict(
90 + (k.lower(), v) for k, v in self.getcontents().items())
91 + self._reverse_key_map = dict(
92 + (k.lower(), k) for k in self.getcontents())
93 +
94 + def _keys_case_insensitive(self):
95 + if self._contents_insensitive is None:
96 + self._case_insensitive_init()
97 + return iter(self._contents_insensitive)
98 +
99 + _keys_case_insensitive.__doc__ = keys.__doc__
100 +
101 + def _contains_case_insensitive(self, key):
102 + if self._contents_insensitive is None:
103 + self._case_insensitive_init()
104 + return key.lower() in self._contents_insensitive
105 +
106 + _contains_case_insensitive.__doc__ = contains.__doc__
107 +
108 + def _unmap_key_case_insensitive(self, key):
109 + if self._reverse_key_map is None:
110 + self._case_insensitive_init()
111 + return self._reverse_key_map[key]
112 +
113 + _unmap_key_case_insensitive.__doc__ = unmap_key.__doc__
114 diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
115 index 8b06f4c..81059b1 100644
116 --- a/pym/portage/dbapi/vartree.py
117 +++ b/pym/portage/dbapi/vartree.py
118 @@ -69,6 +69,7 @@ from _emerge.EbuildPhase import EbuildPhase
119 from _emerge.emergelog import emergelog
120 from _emerge.MiscFunctionsProcess import MiscFunctionsProcess
121 from _emerge.SpawnProcess import SpawnProcess
122 +from ._ContentsCaseSensitivityManager import ContentsCaseSensitivityManager
123
124 import errno
125 import fnmatch
126 @@ -1525,6 +1526,7 @@ class dblink(object):
127 # When necessary, this attribute is modified for
128 # compliance with RESTRICT=preserve-libs.
129 self._preserve_libs = "preserve-libs" in mysettings.features
130 + self._contents = ContentsCaseSensitivityManager(self)
131
132 def __hash__(self):
133 return hash(self._hash_key)
134 @@ -1612,6 +1614,7 @@ class dblink(object):
135 self.contentscache = None
136 self._contents_inodes = None
137 self._contents_basenames = None
138 + self._contents.clear_cache()
139
140 def getcontents(self):
141 """
142 --
143 2.0.4

Replies