]> git.donarmstrong.com Git - neurodebian.git/blob - tools/blends-inject
initial version for blends-inject
[neurodebian.git] / tools / blends-inject
1 #!/usr/bin/python
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:
4
5 __author__ = 'Yaroslav Halchenko'
6 __version__ = 'XXX'
7 __copyright__ = 'Copyright (c) 2010 Yaroslav Halchenko'
8 __license__ = 'GPL'
9
10 import re
11 import os.path
12 from copy import deepcopy
13 from debian_bundle import deb822
14 from debian.changelog import Changelog
15
16 topdir = '/home/yoh/deb/gits/pkg-exppsy/brian'
17
18 blends_file = os.path.join(topdir, 'debian/blends')
19
20
21 def parse_debian_blends(f='debian/blends'):
22     """Parses debian/blends file
23
24     Returns unprocessed list of customized Deb822 entries
25     """
26     # Linearize all the paragraphs since we are not using them
27     items = []
28     for p in deb822.Deb822.iter_paragraphs(open(f)):
29         items += p.items()
30
31     # Traverse and collect things
32     format_ = 'udd'
33     format_clean = False # do not propagate fields into a new pkg if True
34     pkg = None
35     pkgs = []
36     tasks = []
37
38     for k, v in items:
39         k = k.lower()
40         if k == 'format':
41             format_ = v.strip()
42             format_clean = format_.endswith('-clean')
43             if format_clean:
44                 format_ = format_[:-6]
45         elif k == 'tasks':
46             tasks = v.split(',')
47             newtasks = True                 # either we need to provide tune-ups
48                                             # for current package
49         elif k == 'depends':                # new package
50             if format_clean or pkg is None:
51                 pkg = deb822.Deb822()
52             else:
53                 pkg = deepcopy(pkg)
54             pkg['Depends'] = v
55             pkgs.append(pkg)
56             pkg.tasks = dict( (t, deb822.OrderedSet()) for t in tasks )
57             pkg.format = format_
58             newtasks = False
59         else:
60             if newtasks:
61                 # Add customization
62                 for t in tasks:
63                     if not t in pkg.tasks:
64                         pkg.tasks[t] = deb822.Deb822Dict()
65                     pkg.tasks[t][k] = v
66             else:
67                 # just store the key in the pkg itself
68                 pkg[k] = v
69     return pkgs
70
71
72 class DebianMaterials(object):
73     _WNPP_RE = re.compile('^ *\* *Initial release.*closes:? #(?P<bug>[0-9]*).*', re.I)
74
75     def __init__(self, topdir):
76         #self.topdir = topdir
77         self._debiandir = os.path.join(topdir, 'debian')
78         self._source = None
79         self._binaries = None
80
81     @property
82     def source(self):
83         if self._source is None:
84             self._assign_packages()
85         return self._source
86
87     @property
88     def binaries(self):
89         if self._binaries is None:
90             self._assign_packages()
91         return self._binaries
92
93     def fpath(self, name):
94         return os.path.join(self._debiandir, name)
95
96     def _assign_packages(self):
97         try:
98             control = deb822.Deb822.iter_paragraphs(
99                 open(self.fpath('control')))
100         except Exception, e:
101             raise RuntimeError(
102                   "Cannot parse %s file necessary for the %s package entry. Error: %s"
103                   % (control_file, pkg['Depends'], str(e)))
104         self._binaries = {}
105         self._source = None
106         for v in control:
107             if v.get('Source', None):
108                 self._source = v
109             else:
110                 self._binaries[v['Package']] = v
111
112     def get_license(self, package=None, first_only=True):
113         """Return a license(s). Parsed out from debian/copyright if it is
114         in machine readable format
115         """
116         licenses = []
117         # may be package should carry custom copyright file
118         copyright_file_ = self.fpath('%s.copyright' % package)
119         if package and os.path.exists(copyright_file_):
120             copyright_file = copyright_file_
121         else:
122             copyright_file = self.fpath('copyright')
123
124         try:
125             for p in deb822.Deb822.iter_paragraphs(open(copyright_file)):
126                 if not 'Files' in p or p['Files'].strip().startswith('debian/'):
127                     continue
128                 l = p['License']
129                 # Take only the short version of first line
130                 l = re.sub('\n.*', '', l).strip()
131                 if not len(l):
132                     l = 'custom'
133                 if not l in licenses:
134                     licenses.append(l)
135                     if first_only:
136                         break
137         except Exception, e:
138             print e
139             return None
140         return ', '.join(licenses)
141
142     def get_wnpp(self):
143         """Search for a template changelog entry closing "Initial bug
144         """
145         for l in open(self.fpath('changelog')):
146             rr = self._WNPP_RE.match(l)
147             if rr:
148                 return rr.groupdict()['bug']
149         return None
150
151     def get_responsible(self):
152         """Returns responsible, atm -- maintainer
153         """
154         return self.source['Maintainer']
155
156 pkgs = parse_debian_blends(f)
157 #pkgs2 = format_packages()
158 debianm = None
159 # Expand packages which format is complete
160 for pkg in pkgs:
161     if pkg.format == 'complete':
162         # expanding, for that we need debian/control
163         if debianm is None:
164             debianm = DebianMaterials(topdir)
165         for k, m in (('License', lambda: debianm.get_license(pkg['Depends'])),
166                      ('WNPP', debianm.get_wnpp),
167                      ('Pkg-description',
168                       lambda: debianm.binaries[pkg['Depends']]['Description']),
169                      ('Responsible', debianm.get_responsible),
170                      ('Homepage', lambda: debianm.source.get('Homepage', None))):
171             if pkg.get(k, None):
172                 continue
173             v = m()
174             if v:
175                 pkg[k] = v
176         # VCS fields
177
178 print pkgs[0]