Dnia 2014-12-09, o godz. 00:46:28 Michał Górny <[email protected]> napisał(a):
> So considering the previous thread, the Council and QA discussions, I > have prepared a new version of the metadata.xml update. To hopefully > make everyone happy, I come with this three-step process: And the Council meeting brought a bit of update to this. More specifically: 1. type="" is now limited to developer, project and team, corresponding respectively to a single person, a GLEP 39 project (with webpage) and any other kind of group of people [attached]. 2. I've also updated the script to use the new syntax and stop adding <description/> to make things smaller. The herd descriptions are pretty bad-suited for maintainer anyway. 3. herds.xml is to be deprecated as well, with existing herds being replaced by projects (GLEP 39) or teams. 4. We eventually want to migrate to another (simpler, more compact) metadata format, preferably YAML. The exact format is yet to be specced (for example, I have no good ideas of doing restrict="". Does anyone have any more comments or should I proceed with updating the tree for 1+2? Oh, and as usual the current diff is at: http://dev.gentoo.org/~mgorny/tmp/herds.diff.xz -- Best regards, Michał Górny
Index: metadata.dtd =================================================================== RCS file: /var/cvsroot/gentoo/xml/htdocs/dtd/metadata.dtd,v retrieving revision 1.13 diff -u -B -r1.13 metadata.dtd --- metadata.dtd 9 May 2013 06:58:55 -0000 1.13 +++ metadata.dtd 9 Dec 2014 21:28:03 -0000 @@ -13,6 +13,11 @@ <!-- One tag for each maintainer of a package, multiple allowed--> <!ELEMENT maintainer ( email, (description| name)* )> + <!-- maintainer organizational type --> + <!-- developer: regular person --> + <!-- project: GLEP 39 project --> + <!-- team: team that is not a project --> + <!ATTLIST maintainer type (developer|project|team) "developer" > <!-- Natural name for package, example: LibreOffice (for app-office/libreoffice) --> <!ELEMENT natural-name (#PCDATA) >
#!/usr/bin/env python
from collections import namedtuple
import errno
import glob
from lxml.builder import E
import lxml.etree
import os
import os.path
def main():
herdtuple = namedtuple('herdtuple', ('email', 'name'))
herddb = {}
portdir = '/var/db/repos/gentoo'
herdsfile = os.path.join(portdir, 'metadata/herds.xml')
herdsxml = lxml.etree.parse(herdsfile)
for h in herdsxml.getroot():
k = h.find('name').text
e = h.find('email').text
d = h.find('description').text
herddb[k] = herdtuple(e, d)
intree = portdir
outtree = '/tmp/1'
# LAZINESS!
for f in glob.glob(os.path.join(intree, '*/*/metadata.xml')):
subpath = os.path.relpath(f, intree)
print(subpath)
outf = os.path.join(outtree, subpath)
xml = lxml.etree.parse(f)
herds = xml.getroot().findall('herd')
if not herds: # yay, one file less to care about
continue
r = xml.getroot()
maints = r.findall('maintainer')
if maints:
insertpoint = maints[-1]
else:
insertpoint = herds[-1]
# try to guess indentation
def all_texts(node):
first = True
for e in node:
if first:
yield node.text
first = False
yield e.tail
def all_indents(node):
for t in all_texts(node):
if t is None:
yield ''
return
spl = t.split('\n')
# go to last line without text
for l in spl:
if l.lstrip(' \t') != '':
break
# go to the last line
t = l[:len(l) - len(l.lstrip(' \t'))]
yield t
def sub_indents(node):
for e in node:
for x in all_indents(e):
yield x
# some random defaults
indent = '\t'
try:
indent = max(all_indents(r), key=len)
except ValueError:
pass
inner_indent = indent*2 if indent else '\t'
try:
inner_indent = max(sub_indents(r), key=len)
except ValueError:
pass
# start adding new herds after maintainers
for h in herds:
he = herddb[h.text.strip()]
# look for duplicate <herd/> entries
for m in maints:
if m.find('email').text.strip() == he.email:
m.set('type', 'herd')
r.remove(h)
break
else:
attrs = dict(h.items())
attrs['type'] = 'team'
nm = E.maintainer('\n',
inner_indent, E.email(he.email), '\n',
indent,
**attrs
)
nextinsert = insertpoint.getnext()
nm.tail = insertpoint.tail
if nextinsert is not None:
r.insert(r.index(nextinsert), nm)
else:
# avoid extra indent
nm.tail = '\n'
r.append(nm)
insertpoint = nm
# now we can remove it safely
r.remove(h)
# now fix pre-indent
prev = nm.getprevious()
if prev is not None:
prev.tail = '\n' + indent
else:
nm.getparent().text = '\n' + indent
try:
os.makedirs(os.path.dirname(outf))
except OSError as e:
if e.errno != errno.EEXIST:
raise
try:
os.unlink(outf)
except OSError as e:
if e.errno != errno.ENOENT:
raise
xml.write(outf, encoding='UTF-8', xml_declaration='1.0')
# yay, add trailing newline because lxml is dumb
with open(outf, 'ab') as f:
f.write(b'\n')
if __name__ == '__main__':
main()
pgpjbMxDkt5Hl.pgp
Description: OpenPGP digital signature
