initial commit
[ebuildfind.git] / commands / lib / layman / overlay.py
blobfadb59d9a1d32b78b5a0e8da14cb580534ed7fdc
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 #################################################################################
4 # LAYMAN OVERLAY HANDLER
5 #################################################################################
6 # File: overlay.py
8 # Access to an xml list of overlays
10 # Copyright:
11 # (c) 2005 - 2008 Gunnar Wrobel
12 # Distributed under the terms of the GNU General Public License v2
14 # Author(s):
15 # Gunnar Wrobel <wrobel@gentoo.org>
17 '''Main handler for overlays.'''
19 __version__ = "$Id: overlay.py 273 2006-12-30 15:54:50Z wrobel $"
21 #===============================================================================
23 # Dependencies
25 #-------------------------------------------------------------------------------
27 import sys, codecs, os, os.path, xml.dom.minidom
29 from layman.overlays.bzr import BzrOverlay
30 from layman.overlays.darcs import DarcsOverlay
31 from layman.overlays.git import GitOverlay
32 from layman.overlays.mercurial import MercurialOverlay
33 from layman.overlays.cvs import CvsOverlay
34 from layman.overlays.svn import SvnOverlay
35 from layman.overlays.rsync import RsyncOverlay
36 from layman.overlays.tar import TarOverlay
38 from layman.debug import OUT
40 #===============================================================================
42 # Constants
44 #-------------------------------------------------------------------------------
46 OVERLAY_TYPES = {'git' : GitOverlay,
47 'cvs' : CvsOverlay,
48 'svn' : SvnOverlay,
49 'rsync' : RsyncOverlay,
50 'tar' : TarOverlay,
51 'bzr' : BzrOverlay,
52 'mercurial' : MercurialOverlay,
53 'darcs' : DarcsOverlay}
55 #===============================================================================
57 # Class Overlays
59 #-------------------------------------------------------------------------------
61 class Overlays:
62 ''' Handle a list of overlays.'''
64 def __init__(self, paths, ignore = 0, quiet = False):
66 self.quiet = quiet
67 self.paths = paths
68 self.ignore = ignore
70 self.overlays = {}
72 OUT.debug('Initializing overlay list handler', 8)
74 for path in self.paths:
75 if os.path.exists(path):
76 self.read_file(path)
78 def read_file(self, path):
79 '''Read the overlay definition file.'''
81 try:
82 document = open(path).read()
84 except Exception, error:
85 raise IOError('Failed to read the overlay list at ("'
86 + path + '")!\nError was:\n' + str(error))
89 self.read(document)
91 def read(self, document):
92 '''
93 Read an xml list of overlays.
95 >>> here = os.path.dirname(os.path.realpath(__file__))
97 >>> a = Overlays([here + '/tests/testfiles/global-overlays.xml', ])
98 >>> a.overlays.keys()
99 [u'wrobel', u'wrobel-stable']
101 >>> a.overlays['wrobel-stable'].data['&src']
102 u'rsync://gunnarwrobel.de/wrobel-stable'
104 try:
105 document = xml.dom.minidom.parseString(document)
107 except Exception, error:
108 raise Exception('Failed to parse the overlay list!\nError was:\n'
109 + str(error))
111 overlays = document.getElementsByTagName('overlay')
113 for overlay in overlays:
115 OUT.debug('Parsing overlay entry', 8)
117 for index in range(0, overlay.attributes.length):
118 attr = overlay.attributes.item(index)
119 if attr.name == 'type':
120 if attr.nodeValue in OVERLAY_TYPES.keys():
121 try:
122 ovl = OVERLAY_TYPES[attr.nodeValue](overlay,
123 self.ignore,
124 self.quiet)
125 self.overlays[ovl.name] = ovl
126 except Exception, error:
127 OUT.warn(str(error), 3)
128 else:
129 raise Exception('Unknown overlay type "' +
130 attr.nodeValue + '"!')
132 def write(self, path):
134 Write the list of overlays to a file.
136 >>> write = os.tmpnam()
137 >>> here = os.path.dirname(os.path.realpath(__file__))
139 >>> a = Overlays([here + '/tests/testfiles/global-overlays.xml', ])
140 >>> b = Overlays([write,])
141 >>> b.overlays['wrobel-stable'] = a.overlays['wrobel-stable']
142 >>> b.write(write)
143 >>> c = Overlays([write,])
144 >>> c.overlays.keys()
145 [u'wrobel-stable']
147 >>> os.unlink(write)
150 imp = xml.dom.minidom.getDOMImplementation()
152 doc = imp.createDocument('layman', 'overlays', None)
154 root = doc.childNodes[0]
156 for name, overlay in self.overlays.items():
158 root.appendChild(overlay.to_minidom(doc))
160 try:
162 out_file = codecs.open(path, 'w', 'utf-8')
164 doc.writexml(out_file, '', ' ', '\n')
166 except Exception, error:
167 raise Exception('Failed to write to local overlays file: '
168 + path + '\nError was:\n' + str(error))
170 def select(self, overlay):
172 Select an overlay from the list.
174 >>> here = os.path.dirname(os.path.realpath(__file__))
175 >>> a = Overlays([here + '/tests/testfiles/global-overlays.xml', ])
176 >>> a.select('wrobel-stable').data['&src']
177 u'rsync://gunnarwrobel.de/wrobel-stable'
179 if overlay in self.overlays.keys():
180 return self.overlays[overlay]
182 def list(self, verbose = False, width = 0):
184 List all overlays.
186 >>> here = os.path.dirname(os.path.realpath(__file__))
187 >>> a = Overlays([here + '/tests/testfiles/global-overlays.xml', ])
188 >>> for i in a.list(True):
189 ... print i[0]
190 wrobel
191 ~~~~~~
192 Source : https://overlays.gentoo.org/svn/dev/wrobel
193 Contact : nobody@gentoo.org
194 Type : Subversion; Priority: 10
195 <BLANKLINE>
196 Description:
197 Test
198 <BLANKLINE>
199 wrobel-stable
200 ~~~~~~~~~~~~~
201 Source : rsync://gunnarwrobel.de/wrobel-stable
202 Contact : nobody@gentoo.org
203 Type : Rsync; Priority: 50
204 <BLANKLINE>
205 Description:
206 A collection of ebuilds from Gunnar Wrobel [wrobel@gentoo.org].
207 <BLANKLINE>
209 >>> for i in a.list(False, 80):
210 ... print i[0]
211 wrobel [Subversion] (https://o.g.o/svn/dev/wrobel )
212 wrobel-stable [Rsync ] (rsync://gunnarwrobel.de/wrobel-stable)
214 result = []
216 for name, overlay in self.overlays.items():
218 if verbose:
219 result.append((str(overlay), overlay.is_supported(),
220 overlay.is_official()))
221 else:
222 result.append((overlay.short_list(width), overlay.is_supported(),
223 overlay.is_official()))
225 result = sorted(result)
227 return result
229 #===============================================================================
231 # Testing
233 #-------------------------------------------------------------------------------
235 if __name__ == '__main__':
236 import doctest, sys
238 # Ignore warnings here. We are just testing
239 from warnings import filterwarnings, resetwarnings
240 filterwarnings('ignore')
242 doctest.testmod(sys.modules[__name__])
244 resetwarnings()