summaryrefslogtreecommitdiffstats
path: root/meta/lib/bbconfigbuild
diff options
context:
space:
mode:
Diffstat (limited to 'meta/lib/bbconfigbuild')
-rw-r--r--meta/lib/bbconfigbuild/configfragments.py185
1 files changed, 185 insertions, 0 deletions
diff --git a/meta/lib/bbconfigbuild/configfragments.py b/meta/lib/bbconfigbuild/configfragments.py
new file mode 100644
index 0000000000..61c33ac316
--- /dev/null
+++ b/meta/lib/bbconfigbuild/configfragments.py
@@ -0,0 +1,185 @@
1#
2# Copyright OpenEmbedded Contributors
3#
4# SPDX-License-Identifier: GPL-2.0-only
5#
6
7import logging
8import os
9import sys
10import os.path
11
12import bb.utils
13
14from bblayers.common import LayerPlugin
15
16logger = logging.getLogger('bitbake-config-layers')
17
18sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
19
20def plugin_init(plugins):
21 return ConfigFragmentsPlugin()
22
23class ConfigFragmentsPlugin(LayerPlugin):
24 def get_fragment_info(self, path, name):
25 d = bb.data.init()
26 d.setVar('BBPATH', self.tinfoil.config_data.getVar('BBPATH'))
27 bb.parse.handle(path, d, True)
28 summary = d.getVar('BB_CONF_FRAGMENT_SUMMARY')
29 description = d.getVar('BB_CONF_FRAGMENT_DESCRIPTION')
30 if not summary:
31 raise Exception('Please add a one-line summary as BB_CONF_FRAGMENT_SUMMARY = \"...\" variable at the beginning of {}'.format(path))
32
33 if not description:
34 raise Exception('Please add a description as BB_CONF_FRAGMENT_DESCRIPTION = \"...\" variable at the beginning of {}'.format(path))
35
36 return summary, description
37
38 def discover_fragments(self):
39 fragments_path_prefix = self.tinfoil.config_data.getVar('OE_FRAGMENTS_PREFIX')
40 allfragments = {}
41 for layername in self.bbfile_collections:
42 layerdir = self.bbfile_collections[layername]
43 fragments = []
44 for topdir, dirs, files in os.walk(os.path.join(layerdir, fragments_path_prefix)):
45 fragmentdir = os.path.relpath(topdir, os.path.join(layerdir, fragments_path_prefix))
46 for fragmentfile in sorted(files):
47 if fragmentfile.startswith(".") or not fragmentfile.endswith(".conf"):
48 continue
49 fragmentname = os.path.normpath("/".join((layername, fragmentdir, fragmentfile.split('.')[0])))
50 fragmentpath = os.path.join(topdir, fragmentfile)
51 fragmentsummary, fragmentdesc = self.get_fragment_info(fragmentpath, fragmentname)
52 fragments.append({'path':fragmentpath, 'name':fragmentname, 'summary':fragmentsummary, 'description':fragmentdesc})
53 if fragments:
54 allfragments[layername] = {'layerdir':layerdir,'fragments':fragments}
55 return allfragments
56
57 def do_list_fragments(self, args):
58 """ List available configuration fragments """
59 def print_fragment(f, verbose, is_enabled):
60 if not verbose:
61 print('{}\t{}'.format(f['name'], f['summary']))
62 else:
63 print('Name: {}\nPath: {}\nEnabled: {}\nSummary: {}\nDescription:\n{}\n'.format(f['name'], f['path'], 'yes' if is_enabled else 'no', f['summary'],''.join(f['description'])))
64
65 def print_builtin_fragments(builtin, enabled):
66 print('Available built-in fragments:')
67 builtin_dict = {i[0]:i[1] for i in [f.split(':') for f in builtin]}
68 for prefix,var in builtin_dict.items():
69 print('{}/...\tSets {} = ...'.format(prefix, var))
70 print('')
71 enabled_builtin_fragments = [f for f in enabled if self.builtin_fragment_exists(f)]
72 print('Enabled built-in fragments:')
73 for f in enabled_builtin_fragments:
74 prefix, value = f.split('/', 1)
75 print('{}\tSets {} = "{}"'.format(f, builtin_dict[prefix], value))
76 print('')
77
78 all_enabled_fragments = (self.tinfoil.config_data.getVar('OE_FRAGMENTS') or "").split()
79 all_builtin_fragments = (self.tinfoil.config_data.getVar('OE_FRAGMENTS_BUILTIN') or "").split()
80 print_builtin_fragments(all_builtin_fragments, all_enabled_fragments)
81
82 for layername, layerdata in self.discover_fragments().items():
83 layerdir = layerdata['layerdir']
84 fragments = layerdata['fragments']
85 enabled_fragments = [f for f in fragments if f['name'] in all_enabled_fragments]
86 disabled_fragments = [f for f in fragments if f['name'] not in all_enabled_fragments]
87
88 print('Available fragments in {} layer located in {}:\n'.format(layername, layerdir))
89 if enabled_fragments:
90 print('Enabled fragments:')
91 for f in enabled_fragments:
92 print_fragment(f, args.verbose, is_enabled=True)
93 print('')
94 if disabled_fragments:
95 print('Unused fragments:')
96 for f in disabled_fragments:
97 print_fragment(f, args.verbose, is_enabled=False)
98 print('')
99
100 def fragment_exists(self, fragmentname):
101 for layername, layerdata in self.discover_fragments().items():
102 for f in layerdata['fragments']:
103 if f['name'] == fragmentname:
104 return True
105 return False
106
107 def builtin_fragment_exists(self, fragmentname):
108 fragment_prefix = fragmentname.split("/",1)[0]
109 fragment_prefix_defs = set([f.split(':')[0] for f in self.tinfoil.config_data.getVar('OE_FRAGMENTS_BUILTIN').split()])
110 return fragment_prefix in fragment_prefix_defs
111
112 def create_conf(self, confpath):
113 if not os.path.exists(confpath):
114 with open(confpath, 'w') as f:
115 f.write('')
116 with open(confpath, 'r') as f:
117 lines = f.read()
118 if "OE_FRAGMENTS += " not in lines:
119 lines += "\nOE_FRAGMENTS += \"\"\n"
120 with open(confpath, 'w') as f:
121 f.write(lines)
122
123 def do_enable_fragment(self, args):
124 """ Enable a fragment in the local build configuration """
125 def enable_helper(varname, origvalue, op, newlines):
126 enabled_fragments = origvalue.split()
127 for f in args.fragmentname:
128 if f in enabled_fragments:
129 print("Fragment {} already included in {}".format(f, args.confpath))
130 else:
131 enabled_fragments.append(f)
132 return " ".join(enabled_fragments), None, 0, True
133
134 for f in args.fragmentname:
135 if not self.fragment_exists(f) and not self.builtin_fragment_exists(f):
136 raise Exception("Fragment {} does not exist; use 'list-fragments' to see the full list.".format(f))
137
138 self.create_conf(args.confpath)
139 modified = bb.utils.edit_metadata_file(args.confpath, ["OE_FRAGMENTS"], enable_helper)
140 if modified:
141 print("Fragment {} added to {}.".format(", ".join(args.fragmentname), args.confpath))
142
143 def do_disable_fragment(self, args):
144 """ Disable a fragment in the local build configuration """
145 def disable_helper(varname, origvalue, op, newlines):
146 enabled_fragments = origvalue.split()
147 for f in args.fragmentname:
148 if f in enabled_fragments:
149 enabled_fragments.remove(f)
150 else:
151 print("Fragment {} not currently enabled in {}".format(f, args.confpath))
152 return " ".join(enabled_fragments), None, 0, True
153
154 self.create_conf(args.confpath)
155 modified = bb.utils.edit_metadata_file(args.confpath, ["OE_FRAGMENTS"], disable_helper)
156 if modified:
157 print("Fragment {} removed from {}.".format(", ".join(args.fragmentname), args.confpath))
158
159 def do_disable_all_fragments(self, args):
160 """ Disable all fragments in the local build configuration """
161 def disable_all_helper(varname, origvalue, op, newlines):
162 return "", None, 0, True
163
164 self.create_conf(args.confpath)
165 modified = bb.utils.edit_metadata_file(args.confpath, ["OE_FRAGMENTS"], disable_all_helper)
166 if modified:
167 print("All fragments removed from {}.".format(args.confpath))
168
169 def register_commands(self, sp):
170 default_confpath = os.path.join(os.environ["BBPATH"], "conf/auto.conf")
171
172 parser_list_fragments = self.add_command(sp, 'list-fragments', self.do_list_fragments, parserecipes=False)
173 parser_list_fragments.add_argument("--confpath", default=default_confpath, help='Configuration file which contains a list of enabled fragments (default is {}).'.format(default_confpath))
174 parser_list_fragments.add_argument('--verbose', '-v', action='store_true', help='Print extended descriptions of the fragments')
175
176 parser_enable_fragment = self.add_command(sp, 'enable-fragment', self.do_enable_fragment, parserecipes=False)
177 parser_enable_fragment.add_argument("--confpath", default=default_confpath, help='Configuration file which contains a list of enabled fragments (default is {}).'.format(default_confpath))
178 parser_enable_fragment.add_argument('fragmentname', help='The name of the fragment (use list-fragments to see them)', nargs='+')
179
180 parser_disable_fragment = self.add_command(sp, 'disable-fragment', self.do_disable_fragment, parserecipes=False)
181 parser_disable_fragment.add_argument("--confpath", default=default_confpath, help='Configuration file which contains a list of enabled fragments (default is {}).'.format(default_confpath))
182 parser_disable_fragment.add_argument('fragmentname', help='The name of the fragment', nargs='+')
183
184 parser_disable_all = self.add_command(sp, 'disable-all-fragments', self.do_disable_all_fragments, parserecipes=False)
185 parser_disable_all.add_argument("--confpath", default=default_confpath, help='Configuration file which contains a list of enabled fragments (default is {}).'.format(default_confpath))