aboutsummaryrefslogtreecommitdiffstats
path: root/bitbake/bin/bitbake-layers
blob: ed11e5a38656686d72f14b735d3a29ba68f375e3 (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
#!/usr/bin/env python2.6

import cmd
import logging
import os.path
import sys

bindir = os.path.dirname(__file__)
topdir = os.path.dirname(bindir)
sys.path[0:0] = [os.path.join(topdir, 'lib')]

import bb.cache
import bb.cooker
import bb.providers
from bb.cooker import state


logger = logging.getLogger('BitBake')
default_cmd = 'show_appends'


def main(args):
    logging.basicConfig(format='%(levelname)s: %(message)s')
    bb.utils.clean_environment()

    cmds = Commands()
    if args:
        cmds.onecmd(' '.join(args))
    else:
        cmds.onecmd(default_cmd)
    return cmds.returncode


class Commands(cmd.Cmd):
    def __init__(self):
        cmd.Cmd.__init__(self)

        self.returncode = 0
        self.config = Config(parse_only=True)
        self.cooker = bb.cooker.BBCooker(self.config,
                                         self.register_idle_function)
        self.config_data = self.cooker.configuration.data
        bb.providers.logger.setLevel(logging.ERROR)
        self.prepare_cooker()

    def register_idle_function(self, function, data):
        pass

    def prepare_cooker(self):
        sys.stderr.write("Parsing recipes..")
        logger.setLevel(logging.ERROR)

        try:
            while self.cooker.state in (state.initial, state.parsing):
                self.cooker.updateCache()
        except KeyboardInterrupt:
            self.cooker.shutdown()
            self.cooker.updateCache()
            sys.exit(2)

        logger.setLevel(logging.INFO)
        sys.stderr.write("done.\n")

        self.cooker_data = self.cooker.status
        self.cooker_data.appends = self.cooker.appendlist

    def do_show_layers(self, args):
        logger.info(str(self.config_data.getVar('BBLAYERS', True)))

    def do_show_appends(self, args):
        if not self.cooker_data.appends:
            logger.info('No append files found')
            return

        logger.info('State of append files:')

        for pn in self.cooker_data.pkg_pn:
            self.show_appends_for_pn(pn)

        self.show_appends_with_no_recipes()

    def show_appends_for_pn(self, pn):
        filenames = self.cooker_data.pkg_pn[pn]

        best = bb.providers.findBestProvider(pn,
                                             self.cooker.configuration.data,
                                             self.cooker_data,
                                             self.cooker_data.pkg_pn)
        best_filename = os.path.basename(best[3])

        appended, missing = self.get_appends_for_files(filenames)
        if appended:
            for basename, appends in appended:
                logger.info('%s:', basename)
                for append in appends:
                    logger.info('  %s', append)

            if best_filename in missing:
                logger.warn('%s: missing append for preferred version',
                            best_filename)
                self.returncode |= 1

    def get_appends_for_files(self, filenames):
        appended, notappended = set(), set()
        for filename in filenames:
            _, cls = bb.cache.Cache.virtualfn2realfn(filename)
            if cls:
                continue

            basename = os.path.basename(filename)
            appends = self.cooker_data.appends.get(basename)
            if appends:
                appended.add((basename, frozenset(appends)))
            else:
                notappended.add(basename)
        return appended, notappended

    def show_appends_with_no_recipes(self):
        recipes = set(os.path.basename(f)
                      for f in self.cooker_data.pkg_fn.iterkeys())
        appended_recipes = self.cooker_data.appends.iterkeys()
        appends_without_recipes = [self.cooker_data.appends[recipe]
                                   for recipe in appended_recipes
                                   if recipe not in recipes]
        if appends_without_recipes:
            appendlines = ('  %s' % append
                           for appends in appends_without_recipes
                           for append in appends)
            logger.warn('No recipes available for:\n%s',
                        '\n'.join(appendlines))
            self.returncode |= 4

    def do_EOF(self, line):
        return True


class Config(object):
    def __init__(self, **options):
        self.pkgs_to_build = []
        self.debug_domains = []
        self.extra_assume_provided = []
        self.file = []
        self.debug = 0
        self.__dict__.update(options)

    def __getattr__(self, attribute):
        try:
            return super(Config, self).__getattribute__(attribute)
        except AttributeError:
            return None


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]) or 0)