/[gentoo]/src/packages/ebuilddb.py
Gentoo

Contents of /src/packages/ebuilddb.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.8 - (hide annotations) (download) (as text)
Mon Oct 17 05:45:08 2005 UTC (8 years, 11 months ago) by marduk
Branch: MAIN
CVS Tags: v1_3_1, HEAD
Branch point for: v1_3
Changes since 1.7: +8 -3 lines
File MIME type: text/x-python
Backported arch/prevarch db format from pre_2-0

1 marduk 1.4 #!/usr/bin/python -O
2    
3 marduk 1.8 __revision__ = '$Revision: 1.7 $'
4 marduk 1.5 # $Source: /var/cvsroot/gentoo/src/packages/ebuilddb.py,v $
5 marduk 1.1
6     import config
7     import sys
8     import os
9     import time
10     import changelogs
11     import MySQLdb
12    
13     def db_connect():
14     return MySQLdb.connect(host = config.HOST,
15     user = config.USER,
16     passwd = config.PASSWD,
17     db = config.DATABASE)
18 marduk 1.5
19 marduk 1.1 def find_ebuilds():
20     #print "walking..."
21     # yeah, i know we can os.path.walk, but this runs faster ;-)
22     pipe = os.popen("find %s -name '*.ebuild'" % config.PORTAGE_DIR)
23     s = pipe.read()
24     pipe.close()
25     return s.split()
26 marduk 1.5
27 marduk 1.4 def parse_ebuild(s, pkgsplit):
28 marduk 1.1 """Parse ebuild info based on path name"""
29     parsed = {}
30     s=s.split('/')
31     parsed['category'] = s[-3]
32     package = s[-1].split('.ebuild')[0]
33 marduk 1.4 pieces = pkgsplit(package)
34 marduk 1.3 if not pieces:
35     return None
36     parsed['name'] = pieces[0]
37     if pieces[2] == 'r0':
38     parsed['version'] = pieces[1]
39     else:
40     parsed['version'] = '-'.join(pieces[1:])
41 marduk 1.1
42     return parsed
43    
44     def get_ebuild_record(db,ebinfo):
45     c = db.cursor()
46 marduk 1.5 query = ('SELECT * FROM ebuild WHERE category="%s" AND name="%s" '
47 marduk 1.1 'AND version="%s" LIMIT 1' % (ebinfo['category'], ebinfo['name'],
48     ebinfo['version']))
49     c.execute(query)
50     result = c.fetchone()
51     return result
52    
53     def create_ebuild_record(db,ebinfo):
54     c = db.cursor()
55     d = db.cursor()
56     # update the package table
57    
58     # this is a really ugly dict comprehension
59 marduk 1.4 escaped = {}
60     for item in ebinfo.items():
61     x, y = item
62     if type(y) is str:
63     y = MySQLdb.escape_string(y)
64     escaped[x] = y
65 marduk 1.5
66 marduk 1.4 query=('INSERT INTO package SET category="%(category)s",name="%(name)s",'
67     'homepage="%(homepage)s",description="%(description)s",'
68     'license="%(license)s"' % escaped)
69     try:
70     c.execute(query)
71     except MySQLdb.cursors.IntegrityError:
72     # duplicate key (we hope)
73     query = ('REPLACE INTO package VALUES ("%(category)s","%(name)s",'
74     '"%(homepage)s","%(description)s","%(license)s",0)' % escaped)
75     c.execute(query)
76 marduk 1.1
77     # then add particular ebuild
78     query = ('INSERT INTO ebuild VALUES ("%(category)s","%(name)s",'
79 marduk 1.5 '"%(version)s",%(time)s,"%(archs)s","%(changelog)s","",%(masked)d)'
80 marduk 1.1 % escaped)
81     d.execute(query)
82 marduk 1.5
83 marduk 1.1 def update_ebuild_record(db,ebinfo):
84     c = db.cursor()
85 marduk 1.4 escaped = {}
86     for item in ebinfo.items():
87     x, y = item
88     if type(y) is str:
89     y = MySQLdb.escape_string(y)
90     escaped[x] = y
91 marduk 1.5
92 marduk 1.3 query="""REPLACE INTO package VALUES ("%(category)s","%(name)s",\
93 marduk 1.4 "%(homepage)s","%(description)s","%(license)s",0);""" % escaped
94 marduk 1.3 c.execute(query)
95 marduk 1.5
96 marduk 1.1 query = ('UPDATE ebuild '
97     'SET when_found="%(time)s",'
98     'arch="%(archs)s",'
99     'changelog="%(changelog)s",'
100 marduk 1.4 'prevarch="%(prevarch)s", '
101     'is_masked=%(masked)d '
102 marduk 1.1 'WHERE category="%(category)s" '
103     'AND name="%(name)s" '
104     'AND version="%(version)s" ' % escaped)
105 marduk 1.3 try:
106     c.execute(query)
107     except MySQLdb.MySQLError, data:
108     print 'error occurred: '
109     print 'query: %s' % query
110     print 'error: %s' % data
111 marduk 1.5
112 marduk 1.1
113     def get_extended_info(ebuild):
114     filename = os.path.join(config.PORTAGE_DIR,'metadata/cache',
115     ebuild['category'],'%s-%s' % (ebuild['name'],ebuild['version']))
116     try:
117     lines = open(filename,'r').readlines()
118     except IOError:
119 marduk 1.5 print 'Error opening %s' % filename
120 marduk 1.1 lines = []
121     lines = [ s.strip() for s in lines ]
122     try:
123 marduk 1.8 ebuild['archs'] = ','.join(lines[8].split())
124 marduk 1.1 except IndexError:
125     ebuild['archs'] = ''
126     try:
127     ebuild['homepage'] = lines[5]
128     except IndexError:
129     ebuild['homepage'] = 'http://www.gentoo.org/'
130     try:
131     ebuild['license'] = lines[6]
132     except IndexError:
133     ebuild['license'] = ''
134     try:
135     ebuild['description'] = lines[7]
136     except IndexError:
137     ebuild['description'] = ''
138     return ebuild
139    
140     def get_mtime(s):
141     """Get mtime of file, return in format that MySQL would like"""
142     try:
143 marduk 1.7 mtime = os.path.getmtime(s)
144 marduk 1.5 except OSError:
145 marduk 1.1 return 'NULL'
146 marduk 1.7 strftime = time.strftime("%Y%m%d%H%M%S",time.localtime(mtime))
147     return strftime
148 marduk 1.1
149 marduk 1.4 def is_masked(tree, ebuild):
150     """Return true if packages is masked in tree"""
151     return (not tree.visible(['%(category)s/%(name)s-%(version)s' % ebuild]))
152    
153 marduk 1.7 def main(argv = []):
154 marduk 1.6 """Main program entry point"""
155     # We need to "fake" as repoman so portage will ignore local system
156     # settings
157     os.environ['PORTAGE_CALLER'] = 'repoman'
158    
159 marduk 1.1 ebuilds = find_ebuilds()
160     db = db_connect()
161 marduk 1.5
162 marduk 1.4 sys.path = ["/usr/lib/portage/pym"]+sys.path
163     import portage
164     # ... and then wait like a f**king hour
165     sys.path = sys.path[1:]
166    
167     # We want to use the base profile, not any system-specific one
168 marduk 1.5 p_config = portage.config(config_profile_path = '/usr/portage/profiles/base')
169    
170     tree = portage.portdbapi('/usr/portage', p_config)
171    
172 marduk 1.7 # are we updating the db or just rebuilding it?
173     rebuild = len(argv) == 2 and argv[1] == 'rebuild'
174 marduk 1.1 for s in ebuilds:
175 marduk 1.4 fields = parse_ebuild(s, portage.pkgsplit)
176 marduk 1.3 if not fields:
177 marduk 1.1 continue
178     result = get_ebuild_record(db,fields)
179     fields = get_extended_info(fields)
180 marduk 1.5 fields['changelog'] = changelogs.changelog('%s/ChangeLog'
181 marduk 1.1 % os.path.dirname(s))
182     fields['time'] = get_mtime(s)
183 marduk 1.4 fields['masked'] = int(is_masked(tree, fields))
184 marduk 1.5
185 marduk 1.7 if not (result or rebuild):
186 marduk 1.1 create_ebuild_record(db,fields)
187 marduk 1.7 elif result and rebuild:
188     fields['prevarch'] = result[6]
189 marduk 1.8 if ' ' in fields['prevarch']:
190     # old db layout
191     fields['prevarch'] = ','.join(fields['prevarch'].split())
192 marduk 1.7 fields['arch'] = [4]
193     update_ebuild_record(db, fields)
194 marduk 1.8 elif rebuild:
195     pass
196     elif result[4].split(',') != fields['archs'].split(','):
197 marduk 1.1 #print 'ebuild archs=',fields['archs']
198     #print 'db archs=',result[4]
199     #print
200     # keywords change, update db
201     fields['prevarch'] = result[4]
202     update_ebuild_record(db,fields)
203 marduk 1.4 elif result[7] != fields['masked']:
204     #print 'mask changed for %s-%s' % (fields['name'], fields['version'])
205     #print fields['masked']
206     fields['prevarch'] = result[4]
207     update_ebuild_record(db,fields)
208 marduk 1.5
209     db.commit()
210 marduk 1.1 if __name__ == '__main__':
211 marduk 1.7 sys.exit(main(sys.argv))

  ViewVC Help
Powered by ViewVC 1.1.20