source: rtems-source-builder/source-builder/sb/reports.py @ 6ee25e5

4.104.114.95
Last change on this file since 6ee25e5 was 6ee25e5, checked in by Chris Johns <chrisj@…>, on 03/03/13 at 03:52:39

Fix the asciidoc import. Add the missing config files.

  • Property mode set to 100644
File size: 12.5 KB
Line 
1#
2# RTEMS Tools Project (http://www.rtems.org/)
3# Copyright 2010-2013 Chris Johns (chrisj@rtems.org)
4# All rights reserved.
5#
6# This file is part of the RTEMS Tools package in 'rtems-tools'.
7#
8# Permission to use, copy, modify, and/or distribute this software for any
9# purpose with or without fee is hereby granted, provided that the above
10# copyright notice and this permission notice appear in all copies.
11#
12# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
20#
21# This code builds a package given a config file. It only builds to be
22# installed not to be package unless you run a packager around this.
23#
24
25import datetime
26import os
27import sys
28
29try:
30    import build
31    import check
32    import config
33    import defaults
34    import error
35    import git
36    import log
37    import path
38    import setbuilder
39except KeyboardInterrupt:
40    print 'user terminated'
41    sys.exit(1)
42except:
43    print 'unknown application load error'
44    sys.exit(1)
45
46#
47# Version of Sourcer Builder Build.
48#
49version = '0.1'
50
51def _notice(opts, text):
52    if not opts.quiet() and not log.default.has_stdout():
53        print text
54    log.output(text)
55    log.flush()
56
57class report:
58    """Report the build details about a package given a config file."""
59
60    line_len = 78
61
62    def __init__(self, format, _configs, _defaults, opts):
63        self.format = format
64        self.configs = _configs
65        self.defaults = _defaults
66        self.opts = opts
67        self.bset_nesting = 0
68        self.configs_active = False
69        self.out = ''
70        self.asciidoc = None
71
72    def _sbpath(self, *args):
73        p = self.opts.expand('%{_sbdir}', self.defaults)
74        for arg in args:
75            p = path.join(p, arg)
76        return os.path.abspath(path.host(p))
77
78    def output(self, text):
79        self.out += '%s\n' % (text)
80
81    def is_text(self):
82        return self.format == 'text'
83
84    def is_asciidoc(self):
85        return self.format == 'asciidoc'
86
87    def setup(self):
88        if self.is_asciidoc():
89            try:
90                import asciidocapi
91            except:
92                raise error.general('installation error: no asciidocapi found')
93            asciidoc_py = self._sbpath(defaults.basepath, 'asciidoc', 'asciidoc.py')
94            try:
95                self.asciidoc = asciidocapi.AsciiDocAPI(asciidoc_py)
96            except:
97                raise error.general('application error: asciidocapi failed')
98
99    def header(self):
100        pass
101
102    def footer(self):
103        pass
104
105    def git_status(self):
106        text = 'RTEMS Source Builder Repository Status'
107        if self.is_asciidoc():
108            self.output('')
109            self.output("'''")
110            self.output('')
111            self.output('.%s' % (text))
112        else:
113            self.output('-' * self.line_len)
114            self.output('%s' % (text))
115        repo = git.repo('.', self.opts, self.defaults)
116        repo_valid = repo.valid()
117        if repo_valid:
118            if self.is_asciidoc():
119                self.output('*Remotes*:;;')
120            else:
121                self.output(' Remotes:')
122            repo_remotes = repo.remotes()
123            rc = 0
124            for r in repo_remotes:
125                rc += 1
126                if 'url' in repo_remotes[r]:
127                    text = repo_remotes[r]['url']
128                else:
129                    text = 'no URL found'
130                text = '%s: %s' % (r, text)
131                if self.is_asciidoc():
132                    self.output('. %s' % (text))
133                else:
134                    self.output('  %2d: %s' % (rc, text))
135            if self.is_asciidoc():
136                self.output('*Status*:;;')
137            else:
138                self.output(' Status:')
139            if repo.clean():
140                if self.is_asciidoc():
141                    self.output('Clean')
142                else:
143                    self.output('  Clean')
144            else:
145                if self.is_asciidoc():
146                    self.output('_Repository is dirty_')
147                else:
148                    self.output('  Repository is dirty')
149            repo_head = repo.head()
150            if self.is_asciidoc():
151                self.output('*Head*:;;')
152                self.output('Commit: %s' % (repo_head))
153            else:
154                self.output(' Head:')
155                self.output('  Commit: %s' % (repo_head))
156        else:
157            self.output('_Not a valid GIT repository_')
158        if self.is_asciidoc():
159            self.output('')
160            self.output("'''")
161            self.output('')
162
163    def introduction(self, name, intro_text):
164        if self.is_asciidoc():
165            h = 'RTEMS Source Builder Report'
166            self.output(h)
167            self.output('=' * len(h))
168            self.output(':doctype: book')
169            self.output(':toc2:')
170            self.output(':toclevels: 5')
171            self.output(':icons:')
172            self.output(':numbered:')
173            self.output(':data-uri:')
174            self.output('')
175            self.output('RTEMS Tools Project <rtems-users@rtems.org>')
176            self.output(datetime.datetime.now().ctime())
177            self.output('')
178            image = self._sbpath(defaults.basepath, 'images', 'rtemswhitebg.jpg')
179            self.output('image:%s["RTEMS",width="20%%"]' % (image))
180            self.output('')
181            if intro_text:
182                self.output('%s' % ('\n'.join(intro_text)))
183        else:
184            self.output('=' * self.line_len)
185            self.output('RTEMS Tools Project <rtems-users@rtems.org> %s' % datetime.datetime.now().ctime())
186            if intro_text:
187                self.output('')
188                self.output('%s' % ('\n'.join(intro_text)))
189            self.output('=' * self.line_len)
190            self.output('Report: %s' % (name))
191        self.git_status()
192
193    def config_start(self, name):
194        first = not self.configs_active
195        self.configs_active = True
196        if self.is_asciidoc():
197            self.output('.Config: %s' % name)
198            self.output('')
199        else:
200            self.output('-' * self.line_len)
201            self.output('Config: %s' % (name))
202
203    def config_end(self, name):
204        if self.is_asciidoc():
205            self.output('')
206            self.output("'''")
207            self.output('')
208
209    def buildset_start(self, name):
210        if self.is_asciidoc():
211            h = '%s' % (name)
212            self.output('=%s %s' % ('=' * self.bset_nesting, h))
213        else:
214            self.output('=-' * (self.line_len / 2))
215            self.output('Build Set: %s' % (name))
216
217    def buildset_end(self, name):
218        self.configs_active = False
219
220    def source(self, package, source_tag):
221        return package.sources()
222
223    def patch(self, package, args):
224        return package.patches()
225
226    def config(self, name):
227        self.config_start(name)
228        _config = config.file(name, _defaults = self.defaults, opts = self.opts)
229        packages = _config.packages()
230        package = packages['main']
231        name = package.name()
232        if self.is_asciidoc():
233            self.output('*Package*: _%s_' % name)
234            self.output('')
235        else:
236            self.output(' Package: %s' % (name))
237        sources = package.sources()
238        if self.is_asciidoc():
239            self.output('*Sources*:;;')
240            if len(sources) == 0:
241                self.output('No sources')
242        else:
243            self.output('  Sources: %d' % (len(sources)))
244        c = 0
245        for s in sources:
246            c += 1
247            if self.is_asciidoc():
248                self.output('. %s' % (sources[s][0]))
249            else:
250                self.output('   %2d: %s' % (c, sources[s][0]))
251        patches = package.patches()
252        if self.is_asciidoc():
253            self.output('')
254            self.output('*Patches*:;;')
255            if len(patches) == 0:
256                self.output('No patches')
257        else:
258            self.output('  Patches: %s' % (len(patches)))
259        c = 0
260        for p in patches:
261            c += 1
262            if self.is_asciidoc():
263                self.output('. %s' % (patches[p][0]))
264            else:
265                self.output('   %2d: %s' % (c, patches[p][0]))
266        self.config_end(name)
267
268    def buildset(self, name):
269        try_config = False
270        try:
271            self.bset_nesting += 1
272            self.buildset_start(name)
273            bset = setbuilder.buildset(name,
274                                       _configs = self.configs,
275                                       _defaults = self.defaults,
276                                       opts = self.opts)
277            for c in bset.load():
278                if c.endswith('.bset'):
279                    self.buildset(c)
280                elif c.endswith('.cfg'):
281                    self.config(c)
282                else:
283                    raise error.general('invalid config type: %s' % (c))
284            self.buildset_end(name)
285            self.bset_nesting -= 1
286        except error.general, gerr:
287            if gerr.msg.startswith('no build set file found'):
288                try_config = True
289            else:
290                raise
291        if try_config:
292            self.config(name)
293
294    def generate(self, name):
295        if self.is_asciidoc():
296            if self.asciidoc is None:
297                raise error.general('asciidoc not initialised')
298            import StringIO
299            infile = StringIO.StringIO(self.out)
300            outfile = StringIO.StringIO()
301            self.asciidoc.execute(infile, outfile)
302            self.out = outfile.getvalue()
303            infile.close()
304            outfile.close()
305        try:
306            o = open(name, "w")
307            o.write(self.out)
308            o.close()
309            del o
310        except IOError, err:
311            raise error.general('writing output file: %s: %s' % (name, err))
312
313    def make(self, inname, outname, intro_text = None):
314        self.setup()
315        self.introduction(inname, intro_text)
316        self.buildset(inname)
317        self.generate(outname)
318
319def run(args):
320    try:
321        optargs = { '--list-bsets':   'List available build sets',
322                    '--list-configs': 'List available configurations',
323                    '--format':       'Output format (text, asciidoc)',
324                    '--output':       'File name to output the report' }
325        opts, _defaults = defaults.load(args, optargs)
326        log.default = log.log(opts.logfiles())
327        if opts.get_arg('--output') and len(opts.params()) > 1:
328            raise error.general('--output can only be used with a single config')
329        print 'RTEMS Source Builder, Reporter v%s' % (version)
330        if not check.host_setup(opts, _defaults):
331            _notice(opts, 'warning: forcing build with known host setup problems')
332        configs = build.get_configs(opts, _defaults)
333        if not setbuilder.list_bset_cfg_files(opts, configs):
334            output = opts.get_arg('--output')
335            if output is not None:
336                output = output[1]
337            format = 'text'
338            ext = '.txt'
339            format_opt = opts.get_arg('--format')
340            if format_opt:
341                if len(format_opt) != 2:
342                    raise error.general('invalid format option: %s' % ('='.join(format_opt)))
343                if format_opt[1] == 'text':
344                    pass
345                elif format_opt[1] == 'asciidoc':
346                    format = 'asciidoc'
347                    ext = '.html'
348                else:
349                    raise error.general('invalid format: %s' % (format_opt[1]))
350            r = report(format = format,
351                       _configs = configs,
352                       _defaults = _defaults,
353                       opts = opts)
354            for _config in opts.params():
355                if output is None:
356                    outname = path.splitext(_config)[0] + ext
357                else:
358                    outname = output
359                r.make(_config, outname)
360            del r
361    except error.general, gerr:
362        print gerr
363        sys.exit(1)
364    except error.internal, ierr:
365        print ierr
366        sys.exit(1)
367    except error.exit, eerr:
368        pass
369    except KeyboardInterrupt:
370        _notice(opts, 'user terminated')
371        sys.exit(1)
372    sys.exit(0)
373
374if __name__ == "__main__":
375    run(sys.argv)
Note: See TracBrowser for help on using the repository browser.