Gentoo Archives: gentoo-portage-dev

From: Marius Mauch <genone@g.o>
To: gentoo-portage-dev@l.g.o
Subject: Re: [gentoo-portage-dev] [PATCH] inital Manifest2 support
Date: Tue, 22 Nov 2005 20:42:08
Message-Id: 20051122214146.68a9d437@sven.genone.homeip.net
In Reply to: Re: [gentoo-portage-dev] [PATCH] inital Manifest2 support by Brian Harring
1 On Fri, 18 Nov 2005 18:40:14 -0600
2 Brian Harring <ferringb@g.o> wrote:
3
4 > On Wed, Nov 16, 2005 at 04:33:02AM +0100, Marius Mauch wrote:
5 > > - digestfn =
6 > > mysettings["FILESDIR"]+"/digest-"+mysettings["PF"]
7 > > + digestfn =
8 > > portdb.finddigest(mysettings["CATEGORY"]+"/"+mysettings["PF"])
9 > Like this mod personally, but don't like the '/'. You're passing in
10 > two chunks of data, pass them in seperate imo, rather then collapsing
11 > it for every call.
12
13 Not sure I understand this, you mean changing finddigest() to use two
14 params? Doesn't really make sense to me, should just work for any CPV
15 entry.
16
17 > Kind of disliking the 'calledFor' being thrown around here, plus the
18 > v2 check, then resorting to a seperate method of checking.
19 > Integrate 'em potentially?
20 >
21 > You're basically treating it as two seperate funcs (from how I look
22 > at it), should split it up (even if the seperated funcs call each
23 > other, or a common func).
24
25 Yeah, was just going the least intrusive route for now, so keep the API
26 compatible. This wasn't intended for inclusion yet anyway, just some
27 "sneak preview" ;)
28
29 > > @@ -2218,7 +2229,7 @@
30 > > return 1
31 > >
32 > >
33 > > -def digestParseFile(myfilename):
34 > > +def digestParseFile(myfilename, calledFor="manifest"):
35 > > """(filename) -- Parses a given file for entries matching:
36 > > MD5 MD5_STRING_OF_HEX_CHARS FILE_NAME FILE_SIZE
37 > > Ignores lines that do not begin with 'MD5' and returns a
38 > > @@ -2230,6 +2241,10 @@
39 > >
40 > > mydigests={}
41 > > for x in mylines:
42 > > + tmp = portage_manifest.convertManifest2ToDigest(x,
43 > > calledAs=calledFor)
44 > > + if tmp[0] == True:
45 > > + mydigests[tmp[1]] = tmp[2]
46 > > + continue
47 > > myline=string.split(x)
48 > > if len(myline) < 4:
49 > > #invalid line
50 > > @@ -2258,7 +2273,10 @@
51 > > the basedir given. Returns 1 only if all files exist and
52 > > match the md5s. """
53 > > for x in myfiles:
54 > > - if not mydigests.has_key(x):
55 > > + if
56 > > portage_manfest.getManifestVersion(basedir+"/Manifest") == 2 and
57 > > x.startswith("files/digest-"):
58 > hardcoding sucks, kthnx
59 > If possible, try to shove it into the func so modification (down the
60 > line) occurs in one spot, rather then having to resort to
61 > search/replace :)
62
63 Shove what into which func? I'm bad at guessing today.
64
65 >
66 > > Index: pym/portage_checksum.py
67 > > ===================================================================
68 > > --- pym/portage_checksum.py (revision 2312)
69 > > +++ pym/portage_checksum.py (working copy)
70 > > @@ -126,3 +126,12 @@
71 > > portage_locks.unlockfile(mylock)
72 > >
73 > > return (myhash,mysize)
74 > > +
75 > > +
76 > > +hashfunc_map = {"MD5": md5hash, "SHA1": sha1hash}
77 > > +
78 > > +def perform_multiple_checksums(filename, hashes=["MD5"],
79 > > calc_prelink=0):
80 > > + rVal = {}
81 > > + for x in hashes:
82 > > + rVal[x] = perform_checksum(filename,
83 > > hashfunc_map[x], calc_prelink)[0]
84 > > + return rVal
85 > Not sure if I like the [0] tbh.
86 > Still think the size test should be broken off as it's own pseudo
87 > hashfunc, and implemented in that way. Course, would need to weight
88 > it somehow, so that size test is done first, then the more expensive
89 > chf tests...
90
91 Yep, see above about "least intrusive".
92
93 > > --- pym/portage_manifest.py (revision 0)
94 > > +++ pym/portage_manifest.py (revision 0)
95 > > @@ -0,0 +1,163 @@
96 > > +import os
97 > > +
98 > > +import portage, portage_exception, portage_checksum,
99 > > portage_versions +
100 > > +class Manifest2Entry:
101 > > + def __init__(self, entrytype, name, config,
102 > > methods=portage_checksum.get_valid_checksum_keys()):
103 > The methods trick you're doing is a one time evaluation... not sure
104 > if that's the best approach tbh.
105 >
106 > > + if entrytype not in ["EBUILD", "AUXFILE",
107 > > "MISCFILE", "SRCURI"]:
108 > > + raise
109 > > portage_exception.PortageException("unknown Manifest entry type:
110 > > %s" % entrytype)
111 > break that out into a class constant, and please kill off the capps
112 > (they kill kittens, or something).
113
114 Ok on the constant, but I like the caps here ;)
115
116 > > + self.type = entrytype
117 > > + self.name = name
118 > > + self.methods = methods
119 > > + self.config = config
120 > I realize stable does this all over, but I really am not much for
121 > storing a config instance on this attribute.
122 >
123 > Thoughts on yanking the settings you need up front?
124
125 No problem, just took the easy route for now.
126
127 >
128 > > + def generate(self, pkgdir, genOldStyle=True):
129 > > + if self.type == "EBUILD" or self.type ==
130 > > "MISCFILE":
131 > > + filename = pkgdir+"/"+self.name
132 > > + elif self.type == "AUXFILE":
133 > > + filename = pkgdir+"/files/"+self.name
134 > > + elif self.type == "SRCURI":
135 > > + filename =
136 > > self.config["DISTDIR"]+"/"+self.name
137 > > + if not os.path.exists(filename):
138 > > + raise
139 > > portage_exception.PortageException("file for Manifest entry doesn't
140 > > exist: %s" % filename)
141 > > +
142 > > + self.size = os.stat(filename).st_size
143 > > + self.checksums =
144 > > portage_checksum.perform_multiple_checksums(filename, self.methods)
145 > See comment about making size into a pseudo chf func- would eliminate
146 > this case.
147 > Chunking this up into type handlers might be wise- would make it
148 > easier to extend (modify a class dict rather then N funcs). You've
149 > already got the seperated beast, just throw it into a mapping and
150 > it'll be nice and pretty.
151
152 Yeah, though somehow having a function just for filename composition
153 seems a bit overkill. Don't mind either way.
154
155 > > + cs_list = [x+" "+self.checksums[x] for x in
156 > > self.checksums.keys()]
157 > > + self.entry = " ".join([self.type, self.name,
158 > > str(self.size)]+cs_list)
159 > > + if genOldStyle and self.type != "SRCURI":
160 > > + if "MD5" in self.methods:
161 > > + oldentry =
162 > > Manifest2Entry._makeOldEntry(pkgdir, filename, size=self.size,
163 > > md5sum=self.checksums["MD5"])
164 > > + else:
165 > > + oldentry =
166 > > Manifest2Entry._makeOldEntry(pkgdir, filename, size=self.size)
167 > Kinda iffy on this approach also, seems unclean (quite subjective I
168 > realize).
169
170 Better ideas welcome.
171
172 > > +def createFullManifest2(pkgdir, config, checkExisting=False,
173 > > requireAllSrcUriFiles=True, createOldDigests=True,
174 > > manifestCompatible=True, debug=1):
175 > > + mydb = portage.db["/"]["porttree"].dbapi
176 > Really don't like that.
177 > Pass it in.
178
179 No problem.
180
181 > > +
182 > > + if debug:
183 > > + print "pkgdir:", pkgdir
184 > > +
185 > > + cpv_list = [pkgdir.rstrip("/").split("/")[-2]+"/"+x[:-7]
186 > > for x in portage.listdir(pkgdir) if x.endswith(".ebuild")]
187 > os.path.sep...
188
189 Cosmetics.
190
191 > not much for the portage.listdir reference there either, kind of an
192 > indication the evil listdir/cachedir should be broken out into their
193 > own module.
194
195 Beyond the scope of this patch.
196
197 > > +
198 > > + return (0, None)
199 > Eh?
200 > Exceptions seem like a better route here then magic constants and
201 > string error msgs.
202
203 Eh, I don't return error messages but the name of the object that
204 caused the failure. Wether to use exceptions for this comes down on who
205 is going to call this, don't really see the point in using exceptions
206 here as I expect only two or three callers (namely repoman and ebuild)
207 which have to act on the return code directly.
208
209 > > +def convertManifest2ToDigest(manifestline, calledAs="manifest"):
210 > > + mysplit = manifestline.split()
211 > > + if mysplit[0] not in ["EBUILD", "AUXFILE", "MISCFILE",
212 > > "SRCURI"] or ((len(mysplit) - 3) % 2) != 0:
213 > > + return (False, None, None)
214 > > + if mysplit[0] == "SRCURI" and calledAs == "manifest":
215 > > + return (False, None, None)
216 > > + if mysplit[0] in ["EBUILD", "AUXFILE", "MISCFILE"] and
217 > > calledAs == "digest":
218 > > + return (False, None, None)
219 > > +
220 > > + checksums = {}
221 > > +
222 > > + mytype = mysplit.pop(0)
223 > > + filename = mysplit.pop(0)
224 > > + if mytype == "AUXFILE":
225 > > + filename = "files/"+filename
226 > > + size = long(mysplit.pop(0))
227 > > + checksums = dict(zip(mysplit[::2], mysplit[1::2]))
228 > > + if not checksums.has_key("size"):
229 > > + checksums["size"] = size
230 > > +
231 > > + return (True, filename, checksums)
232 > > +
233 > > +def getManifestVersion(manifest):
234 > > + rVal = 0
235 > > +
236 > > + if not os.path.exists(manifest):
237 > > + return rVal
238 > > + myfile = open(manifest, "r")
239 > > + lines = myfile.readlines()
240 > > + for l in lines:
241 > > + mysplit = l.split()
242 > > + if mysplit[0] == "MD5" and len(mysplit) == 4 and
243 > > rVal == 0:
244 > > + rVal = 1
245 > > + elif mysplit[0] in ["EBUILD", "AUXFILE",
246 > > "MISCFILE", "SRCURI"] and ((len(mysplit) - 3) % 2) == 0 and rVal in
247 > > [0,1]:
248 > > + rVal = 2
249 > > + return rVal
250 >
251 > Offhand... I really think you need to do some subclassing above.
252 > Flow's mostly there, but a lot of icky stuff for long term
253 > maintenance (imo). Seems like a refactoring of the patch would bring
254 > line count down, and up readability.
255
256 Maybe, but I'm no such an OO maniac and also suck at refactoring ;)
257
258 Marius
259
260 --
261 Public Key at http://www.genone.de/info/gpg-key.pub
262
263 In the beginning, there was nothing. And God said, 'Let there be
264 Light.' And there was still nothing, but you could see a bit better.

Attachments

File name MIME type
signature.asc application/pgp-signature

Replies

Subject Author
Re: [gentoo-portage-dev] [PATCH] inital Manifest2 support Brian Harring <ferringb@g.o>