diff options
Diffstat (limited to 'meta/lib/bblayers/makesetup.py')
-rw-r--r-- | meta/lib/bblayers/makesetup.py | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/meta/lib/bblayers/makesetup.py b/meta/lib/bblayers/makesetup.py new file mode 100644 index 0000000000..99d5973760 --- /dev/null +++ b/meta/lib/bblayers/makesetup.py | |||
@@ -0,0 +1,102 @@ | |||
1 | # | ||
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: GPL-2.0-only | ||
5 | # | ||
6 | |||
7 | import logging | ||
8 | import os | ||
9 | import sys | ||
10 | |||
11 | import bb.utils | ||
12 | |||
13 | from bblayers.common import LayerPlugin | ||
14 | |||
15 | logger = logging.getLogger('bitbake-layers') | ||
16 | |||
17 | sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) | ||
18 | |||
19 | import oe.buildcfg | ||
20 | |||
21 | def plugin_init(plugins): | ||
22 | return MakeSetupPlugin() | ||
23 | |||
24 | class MakeSetupPlugin(LayerPlugin): | ||
25 | |||
26 | def _get_remotes_with_url(self, repo_path): | ||
27 | remotes = {} | ||
28 | for r in oe.buildcfg.get_metadata_git_remotes(repo_path): | ||
29 | remotes[r] = {'uri':oe.buildcfg.get_metadata_git_remote_url(repo_path, r)} | ||
30 | return remotes | ||
31 | |||
32 | def _is_submodule(self, repo_path): | ||
33 | # This is slightly brittle: git does not offer a way to tell whether | ||
34 | # a given repo dir is a submodule checkout, so we need to rely on .git | ||
35 | # being a file (rather than a dir like it is in standalone checkouts). | ||
36 | # The file typically contains a gitdir pointer to elsewhere. | ||
37 | return os.path.isfile(os.path.join(repo_path,".git")) | ||
38 | |||
39 | def make_repo_config(self, destdir): | ||
40 | """ This is a helper function for the writer plugins that discovers currently configured layers. | ||
41 | The writers do not have to use it, but it can save a bit of work and avoid duplicated code, hence it is | ||
42 | available here. """ | ||
43 | repos = {} | ||
44 | layers = oe.buildcfg.get_layer_revisions(self.tinfoil.config_data) | ||
45 | destdir_repo = oe.buildcfg.get_metadata_git_toplevel(destdir) | ||
46 | |||
47 | for (l_path, l_name, l_branch, l_rev, l_ismodified) in layers: | ||
48 | if l_name == 'workspace': | ||
49 | continue | ||
50 | if l_ismodified: | ||
51 | logger.error("Layer {name} in {path} has uncommitted modifications or is not in a git repository.".format(name=l_name,path=l_path)) | ||
52 | return | ||
53 | repo_path = oe.buildcfg.get_metadata_git_toplevel(l_path) | ||
54 | |||
55 | if self._is_submodule(repo_path): | ||
56 | continue | ||
57 | if repo_path not in repos.keys(): | ||
58 | repos[repo_path] = {'path':os.path.basename(repo_path),'git-remote':{ | ||
59 | 'rev':l_rev, | ||
60 | 'branch':l_branch, | ||
61 | 'remotes':self._get_remotes_with_url(repo_path), | ||
62 | 'describe':oe.buildcfg.get_metadata_git_describe(repo_path)}} | ||
63 | if repo_path == destdir_repo: | ||
64 | repos[repo_path]['contains_this_file'] = True | ||
65 | if not repos[repo_path]['git-remote']['remotes'] and not repos[repo_path]['contains_this_file']: | ||
66 | logger.error("Layer repository in {path} does not have any remotes configured. Please add at least one with 'git remote add'.".format(path=repo_path)) | ||
67 | return | ||
68 | |||
69 | top_path = os.path.commonpath([os.path.dirname(r) for r in repos.keys()]) | ||
70 | |||
71 | repos_nopaths = {} | ||
72 | for r in repos.keys(): | ||
73 | r_nopath = os.path.basename(r) | ||
74 | repos_nopaths[r_nopath] = repos[r] | ||
75 | r_relpath = os.path.relpath(r, top_path) | ||
76 | repos_nopaths[r_nopath]['path'] = r_relpath | ||
77 | return repos_nopaths | ||
78 | |||
79 | def do_make_setup(self, args): | ||
80 | """ Writes out a configuration file and/or a script that replicate the directory structure and revisions of the layers in a current build. """ | ||
81 | for p in self.plugins: | ||
82 | if str(p) == args.writer: | ||
83 | p.do_write(self, args) | ||
84 | |||
85 | def register_commands(self, sp): | ||
86 | parser_setup_layers = self.add_command(sp, 'create-layers-setup', self.do_make_setup, parserecipes=False) | ||
87 | parser_setup_layers.add_argument('destdir', | ||
88 | help='Directory where to write the output\n(if it is inside one of the layers, the layer becomes a bootstrap repository and thus will be excluded from fetching).') | ||
89 | parser_setup_layers.add_argument('--output-prefix', '-o', | ||
90 | help='File name prefix for the output files, if the default (setup-layers) is undesirable.') | ||
91 | |||
92 | self.plugins = [] | ||
93 | |||
94 | for path in (self.tinfoil.config_data.getVar('BBPATH').split(':')): | ||
95 | pluginpath = os.path.join(path, 'lib', 'bblayers', 'setupwriters') | ||
96 | bb.utils.load_plugins(logger, self.plugins, pluginpath) | ||
97 | |||
98 | parser_setup_layers.add_argument('--writer', '-w', choices=[str(p) for p in self.plugins], help="Choose the output format (defaults to oe-setup-layers).\n\nCurrently supported options are:\noe-setup-layers - a self-contained python script and a json config for it.\n\n", default="oe-setup-layers") | ||
99 | |||
100 | for plugin in self.plugins: | ||
101 | if hasattr(plugin, 'register_arguments'): | ||
102 | plugin.register_arguments(parser_setup_layers) | ||