diff options
| -rw-r--r-- | bitbake/bin/bitbake-layers | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/bitbake/bin/bitbake-layers b/bitbake/bin/bitbake-layers new file mode 100644 index 0000000000..08a846be81 --- /dev/null +++ b/bitbake/bin/bitbake-layers | |||
| @@ -0,0 +1,153 @@ | |||
| 1 | #!/usr/bin/env python2.6 | ||
| 2 | |||
| 3 | import cmd | ||
| 4 | import logging | ||
| 5 | import os.path | ||
| 6 | import sys | ||
| 7 | |||
| 8 | bindir = os.path.dirname(__file__) | ||
| 9 | topdir = os.path.dirname(bindir) | ||
| 10 | sys.path[0:0] = [os.path.join(topdir, 'lib')] | ||
| 11 | |||
| 12 | import bb.cache | ||
| 13 | import bb.cooker | ||
| 14 | import bb.providers | ||
| 15 | from bb.cooker import state | ||
| 16 | |||
| 17 | |||
| 18 | logger = logging.getLogger('BitBake') | ||
| 19 | default_cmd = 'show_appends' | ||
| 20 | |||
| 21 | |||
| 22 | def main(args): | ||
| 23 | logging.basicConfig(format='%(levelname)s: %(message)s') | ||
| 24 | |||
| 25 | cmds = Commands() | ||
| 26 | if args: | ||
| 27 | cmds.onecmd(' '.join(args)) | ||
| 28 | else: | ||
| 29 | cmds.onecmd(default_cmd) | ||
| 30 | return cmds.returncode | ||
| 31 | |||
| 32 | |||
| 33 | class Commands(cmd.Cmd): | ||
| 34 | def __init__(self): | ||
| 35 | cmd.Cmd.__init__(self) | ||
| 36 | |||
| 37 | self.returncode = 0 | ||
| 38 | self.config = Config(parse_only=True) | ||
| 39 | self.cooker = bb.cooker.BBCooker(self.config, | ||
| 40 | self.register_idle_function) | ||
| 41 | self.config_data = self.cooker.configuration.data | ||
| 42 | bb.providers.logger.setLevel(logging.ERROR) | ||
| 43 | self.prepare_cooker() | ||
| 44 | |||
| 45 | def register_idle_function(self, function, data): | ||
| 46 | pass | ||
| 47 | |||
| 48 | def prepare_cooker(self): | ||
| 49 | sys.stderr.write("Parsing recipes..") | ||
| 50 | logger.setLevel(logging.ERROR) | ||
| 51 | |||
| 52 | try: | ||
| 53 | while self.cooker.state in (state.initial, state.parsing): | ||
| 54 | self.cooker.updateCache() | ||
| 55 | except KeyboardInterrupt: | ||
| 56 | self.cooker.shutdown() | ||
| 57 | self.cooker.updateCache() | ||
| 58 | sys.exit(2) | ||
| 59 | |||
| 60 | logger.setLevel(logging.INFO) | ||
| 61 | sys.stderr.write("done.\n") | ||
| 62 | |||
| 63 | self.cooker_data = self.cooker.status | ||
| 64 | self.cooker_data.appends = self.cooker.appendlist | ||
| 65 | |||
| 66 | def do_show_layers(self, args): | ||
| 67 | logger.info(str(self.config_data.getVar('BBLAYERS', True))) | ||
| 68 | |||
| 69 | def do_show_appends(self, args): | ||
| 70 | if not self.cooker_data.appends: | ||
| 71 | logger.info('No append files found') | ||
| 72 | return | ||
| 73 | |||
| 74 | logger.info('State of append files:') | ||
| 75 | |||
| 76 | for pn in self.cooker_data.pkg_pn: | ||
| 77 | self.show_appends_for_pn(pn) | ||
| 78 | |||
| 79 | self.show_appends_with_no_recipes() | ||
| 80 | |||
| 81 | def show_appends_for_pn(self, pn): | ||
| 82 | filenames = self.cooker_data.pkg_pn[pn] | ||
| 83 | |||
| 84 | best = bb.providers.findBestProvider(pn, | ||
| 85 | self.cooker.configuration.data, | ||
| 86 | self.cooker_data, | ||
| 87 | self.cooker_data.pkg_pn) | ||
| 88 | best_filename = os.path.basename(best[3]) | ||
| 89 | |||
| 90 | appended, missing = self.get_appends_for_files(filenames) | ||
| 91 | if appended: | ||
| 92 | for basename, appends in appended: | ||
| 93 | logger.info('%s:', basename) | ||
| 94 | for append in appends: | ||
| 95 | logger.info(' %s', append) | ||
| 96 | |||
| 97 | if best_filename in missing: | ||
| 98 | logger.warn('%s: missing append for preferred version', | ||
| 99 | best_filename) | ||
| 100 | self.returncode |= 1 | ||
| 101 | |||
| 102 | def get_appends_for_files(self, filenames): | ||
| 103 | appended, notappended = set(), set() | ||
| 104 | for filename in filenames: | ||
| 105 | _, cls = bb.cache.Cache.virtualfn2realfn(filename) | ||
| 106 | if cls: | ||
| 107 | continue | ||
| 108 | |||
| 109 | basename = os.path.basename(filename) | ||
| 110 | appends = self.cooker_data.appends.get(basename) | ||
| 111 | if appends: | ||
| 112 | appended.add((basename, frozenset(appends))) | ||
| 113 | else: | ||
| 114 | notappended.add(basename) | ||
| 115 | return appended, notappended | ||
| 116 | |||
| 117 | def show_appends_with_no_recipes(self): | ||
| 118 | recipes = set(os.path.basename(f) | ||
| 119 | for f in self.cooker_data.pkg_fn.iterkeys()) | ||
| 120 | appended_recipes = self.cooker_data.appends.iterkeys() | ||
| 121 | appends_without_recipes = [self.cooker_data.appends[recipe] | ||
| 122 | for recipe in appended_recipes | ||
| 123 | if recipe not in recipes] | ||
| 124 | if appends_without_recipes: | ||
| 125 | appendlines = (' %s' % append | ||
| 126 | for appends in appends_without_recipes | ||
| 127 | for append in appends) | ||
| 128 | logger.warn('No recipes available for:\n%s', | ||
| 129 | '\n'.join(appendlines)) | ||
| 130 | self.returncode |= 4 | ||
| 131 | |||
| 132 | def do_EOF(self, line): | ||
| 133 | return True | ||
| 134 | |||
| 135 | |||
| 136 | class Config(object): | ||
| 137 | def __init__(self, **options): | ||
| 138 | self.pkgs_to_build = [] | ||
| 139 | self.debug_domains = [] | ||
| 140 | self.extra_assume_provided = [] | ||
| 141 | self.file = [] | ||
| 142 | self.debug = 0 | ||
| 143 | self.__dict__.update(options) | ||
| 144 | |||
| 145 | def __getattr__(self, attribute): | ||
| 146 | try: | ||
| 147 | return super(Config, self).__getattribute__(attribute) | ||
| 148 | except AttributeError: | ||
| 149 | return None | ||
| 150 | |||
| 151 | |||
| 152 | if __name__ == '__main__': | ||
| 153 | sys.exit(main(sys.argv[1:]) or 0) | ||
