aboutsummaryrefslogtreecommitdiff
blob: fd59e4bf210970255f4c48ffb54dd3905e646459 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
#!/usr/bin/python
##############################################################################
# $Header: $
##############################################################################
# Distributed under the terms of the GNU General Public License, v2 or later
# Author: Ned Ludd <solar@gentoo.org> (glue all the parts together)
# Author: Eldad Zack <eldad@gentoo.org> (earch)
# Author : Eric Olinger <EvvL AT RustedHalo DOT net> (metadata)

# Gentoo metadata xml and arch keyword checking tool.

import os
import sys
import re
from stat import *
from xml.sax import saxutils, make_parser, handler
from xml.sax.handler import feature_namespaces

import portage
from portage.output import *

__version__ = "svn"

def earch(workdir):
	"""Prints arch keywords for a given dir"""
	portdir = portage.settings["PORTDIR"]
	#workdir = "."
	os.chdir(workdir)

	archdict = {}
	ebuildlist = []
	for file in os.listdir(workdir):
		if re.search("\.ebuild$",file):
			ebuildlist.append(re.split("\.ebuild$",file)[0])

	ebuildlist.sort(lambda x,y: portage.pkgcmp(portage.pkgsplit(x),portage.pkgsplit(y)))

	slot_list = []

	for pkg in ebuildlist:		
		portdb = portage.portdbapi(portdir)
		aux = portdb.aux_get(workdir.rsplit("/")[-2] + "/" + pkg, ['SLOT', 'KEYWORDS'])
		
		slot = aux[0]
		keywords = keywords = re.split(' ',aux[1])
		
		if not slot in slot_list:
			slot_list.append(slot)
		
		for arch in keywords:
			if arch in archdict:
				archdict[arch].append((pkg, slot))
			else:
				archdict[arch] = [ (pkg, slot) ]

	archlist = archdict.keys();
	archlist.sort()

	slot_list.sort()

	for slot in slot_list:
		visible_stable = {}
		visible_unstable = {}
		
		for arch in archlist:
			visible_stable[arch] = None
			visible_unstable[arch] = None
			
		for pkg in ebuildlist:
			for arch in archlist:
				if (arch and (pkg, slot) in archdict[arch]):
					if arch[0] == "-":
						pass
					elif "~" == arch[0]:
						visible_unstable[arch] = pkg
					else:
						visible_unstable["~" + arch] = None
						visible_stable[arch] = pkg
		
		for pkg in ebuildlist:
			found = False
			for arch in archlist:
				if (pkg, slot) in archdict[arch]:
					found = True
			
			if not found:
				continue
			
			if not pkg == ebuildlist[0]:
				print ""
				
			print darkgreen("Keywords: ") + pkg + "[" + slot + "]:",
			
			for arch in archlist:
				if (arch and (pkg, slot) in archdict[arch]):
					if arch[0] == "-":
						print red(arch),
					elif "~" == arch[0]:
						if visible_unstable[arch] == pkg:
							print blue(arch),
					else:
						if visible_stable[arch] == pkg:
							print green(arch),


class Metadata_XML(handler.ContentHandler):
	_inside_herd="No"
	_inside_maintainer="No"
	_inside_email="No"
	_inside_longdescription="No"

	_herd = []
	_maintainers = []
	_longdescription = ""

	def startElement(self, tag, attr):
		if tag == "herd":
			self._inside_herd="Yes"
		if tag == "longdescription":
			self._inside_longdescription="Yes"
		if tag == "maintainer":
			self._inside_maintainer="Yes"
		if tag == "email":
			self._inside_email="Yes"

	def endElement(self, tag):
		if tag == "herd":
			self._inside_herd="No"
		if tag == "longdescription":
			self._inside_longdescription="No"
		if tag == "maintainer":
			self._inside_maintainer="No"
		if tag == "email":
			self._inside_email="No"

	def characters(self, contents):
		if self._inside_herd == "Yes":
			self._herd.append(contents)

		if self._inside_longdescription == "Yes":
			self._longdescription = contents
			
		if self._inside_maintainer=="Yes" and self._inside_email=="Yes":
			self._maintainers.append(contents)


def check_metadata(full_package):
	"""Checks that the primary maintainer is still an active dev and list the herd the package belongs to"""
	metadata_file=portage.settings["PORTDIR"] + "/" + portage.pkgsplit(full_package)[0] + "/metadata.xml"
	if not os.path.exists(metadata_file):
		print darkgreen("Maintainer: ") + red("Error (Missing metadata.xml)")
		return 1

	parser = make_parser()
	handler = Metadata_XML()
	handler._maintainers = []
	parser.setContentHandler(handler)
	parser.parse( metadata_file )

	if handler._herd:
		herds = ", ".join(handler._herd)
		print darkgreen("Herd: ") + herds
	else:       
		print darkgreen("Herd: ") + red("Error (No Herd)")
		return 1


	if handler._maintainers:
		print darkgreen("Maintainer: ") + ", ".join(handler._maintainers)
	else:
		print darkgreen("Maintainer: ") + "none"

	if len(handler._longdescription) > 1:
		print darkgreen("Description: ") + handler._longdescription
	print darkgreen("Location: ") + os.path.normpath(portage.settings["PORTDIR"] + "/" + portage.pkgsplit(full_package)[0])


def usage(code):
	"""Prints the uage information for this script"""
	print green("epkginfo"), "(%s)" % __version__
	print
	print "Usage: epkginfo [package-cat/]package"
	sys.exit(code)


# default color setup
if ( not sys.stdout.isatty() ) or ( portage.settings["NOCOLOR"] in ["yes","true"] ):
	nocolor()

def fc(x,y):
	return cmp(y[0], x[0])


def grab_changelog_devs(catpkg):
	try:
		os.chdir(portage.settings["PORTDIR"] + "/" + catpkg)
		foo=""
		r=re.compile("<[^@]+@gentoo.org>", re.I)
		s="\n".join(portage.grabfile("ChangeLog"))
		d={}
		for x in r.findall(s):
			if x not in d:
				d[x] = 0
			d[x] += 1

		l=[(d[x], x) for x in d.keys()]
		#l.sort(lambda x,y: cmp(y[0], x[0]))
		l.sort(fc)
		for x in l:
			p = str(x[0]) +" "+ x[1].lstrip("<").rstrip(">")
			foo += p[:p.find("@")]+", "
		return foo
	except:
		raise

def main ():
	if len( sys.argv ) < 2:
		usage(1)

	for pkg in sys.argv[1:]:

		if sys.argv[1:][:1] == "-":
			print "NOT WORKING?=="+sys.argv[1:]
			continue

		try:
			package_list = portage.portdb.xmatch("match-all", pkg)
			if package_list:

				catpkg = portage.pkgsplit(package_list[0])[0]

				print darkgreen("Package: ") + catpkg
				check_metadata(package_list[0])
				earch(portage.settings["PORTDIR"] + "/" + catpkg)
				#print darkgreen("ChangeLog: ") + grab_changelog_devs(catpkg)
				print ""
			else:
				print "!!! No package '%s'" % pkg
		except:
			print red("Error: "+pkg+"\n")


if __name__ == '__main__':
	main()