2 #emacs: -*- mode: python-mode; py-indent-offset: 4; tab-width: 4; indent-tabs-mode: nil -*-
3 #ex: set sts=4 ts=4 sw=4 noet:
5 __author__ = 'Yaroslav Halchenko'
7 __copyright__ = 'Copyright (c) 2010 Yaroslav Halchenko'
12 from copy import deepcopy
13 from debian_bundle import deb822
14 from debian.changelog import Changelog
16 topdir = '/home/yoh/deb/gits/pkg-exppsy/brian'
18 blends_file = os.path.join(topdir, 'debian/blends')
21 def parse_debian_blends(f='debian/blends'):
22 """Parses debian/blends file
24 Returns unprocessed list of customized Deb822 entries
26 # Linearize all the paragraphs since we are not using them
28 for p in deb822.Deb822.iter_paragraphs(open(f)):
31 # Traverse and collect things
33 format_clean = False # do not propagate fields into a new pkg if True
42 format_clean = format_.endswith('-clean')
44 format_ = format_[:-6]
47 newtasks = True # either we need to provide tune-ups
49 elif k == 'depends': # new package
50 if format_clean or pkg is None:
56 pkg.tasks = dict( (t, deb822.OrderedSet()) for t in tasks )
63 if not t in pkg.tasks:
64 pkg.tasks[t] = deb822.Deb822Dict()
67 # just store the key in the pkg itself
71 def expand_pkgs(pkgs):
72 """In-place modification of pkgs taking if necessary additional
73 information from Debian materials, and pruning empty fields
76 # Expand packages which format is complete
78 if pkg.format == 'complete':
79 # expanding, for that we need debian/control
81 debianm = DebianMaterials(topdir)
82 for k, m in (('License', lambda: debianm.get_license(pkg['Depends'])),
83 ('WNPP', debianm.get_wnpp),
85 lambda: debianm.binaries[pkg['Depends']]['Description']),
86 ('Responsible', debianm.get_responsible),
87 ('Homepage', lambda: debianm.source.get('Homepage', None))):
94 pkg.update(debianm.get_vcsfields())
96 # Perform string completions and removals
97 for k,v in pkg.iteritems():
99 if v is None or not len(v.strip()):
102 class DebianMaterials(object):
103 """Extract selected information from an existing debian/
105 _WNPP_RE = re.compile('^ *\* *Initial release.*closes:? #(?P<bug>[0-9]*).*', re.I)
107 def __init__(self, topdir):
108 #self.topdir = topdir
109 self._debiandir = os.path.join(topdir, 'debian')
111 self._binaries = None
115 if self._source is None:
116 self._assign_packages()
121 if self._binaries is None:
122 self._assign_packages()
123 return self._binaries
125 def fpath(self, name):
126 return os.path.join(self._debiandir, name)
128 def _assign_packages(self):
130 control = deb822.Deb822.iter_paragraphs(
131 open(self.fpath('control')))
134 "Cannot parse %s file necessary for the %s package entry. Error: %s"
135 % (control_file, pkg['Depends'], str(e)))
139 if v.get('Source', None):
142 self._binaries[v['Package']] = v
144 def get_license(self, package=None, first_only=True):
145 """Return a license(s). Parsed out from debian/copyright if it is
146 in machine readable format
149 # may be package should carry custom copyright file
150 copyright_file_ = self.fpath('%s.copyright' % package)
151 if package and os.path.exists(copyright_file_):
152 copyright_file = copyright_file_
154 copyright_file = self.fpath('copyright')
157 for p in deb822.Deb822.iter_paragraphs(open(copyright_file)):
158 if not 'Files' in p or p['Files'].strip().startswith('debian/'):
161 # Take only the short version of first line
162 l = re.sub('\n.*', '', l).strip()
165 if not l in licenses:
172 return ', '.join(licenses)
175 """Search for a template changelog entry closing "Initial bug
177 for l in open(self.fpath('changelog')):
178 rr = self._WNPP_RE.match(l)
180 return rr.groupdict()['bug']
183 def get_responsible(self):
184 """Returns responsible, atm -- maintainer
186 return self.source['Maintainer']
188 def get_vcsfields(self):
189 vcs = deb822.Deb822()
190 for f,v in self._source.iteritems():
191 if f.lower().startswith('vcs-'):
195 pkgs = parse_debian_blends(blends_file)
198 print '\n'.join(str(p) for p in pkgs)