blob: 77b74cb730a04b7c46fa204ba02f7e7210712840 [file] [log] [blame]
Patrick Williamsd7e96312015-09-22 08:09:05 -05001# Recipe creation tool - newappend plugin
2#
3# This sub-command creates a bbappend for the specified target and prints the
4# path to the bbappend.
5#
6# Example: recipetool newappend meta-mylayer busybox
7#
8# Copyright (C) 2015 Christopher Larson <kergoth@gmail.com>
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License version 2 as
12# published by the Free Software Foundation.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License along
20# with this program; if not, write to the Free Software Foundation, Inc.,
21# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
23import argparse
24import errno
25import logging
26import os
27import re
28import sys
29
30
31logger = logging.getLogger('recipetool')
32tinfoil = None
33
34
35def plugin_init(pluginlist):
36 # Don't need to do anything here right now, but plugins must have this function defined
37 pass
38
39
40def tinfoil_init(instance):
41 global tinfoil
42 tinfoil = instance
43
44
45def _provide_to_pn(cooker, provide):
46 """Get the name of the preferred recipe for the specified provide."""
47 import bb.providers
48 filenames = cooker.recipecache.providers[provide]
49 eligible, foundUnique = bb.providers.filterProviders(filenames, provide, cooker.expanded_data, cooker.recipecache)
50 filename = eligible[0]
51 pn = cooker.recipecache.pkg_fn[filename]
52 return pn
53
54
55def _get_recipe_file(cooker, pn):
56 import oe.recipeutils
57 recipefile = oe.recipeutils.pn_to_recipe(cooker, pn)
58 if not recipefile:
59 skipreasons = oe.recipeutils.get_unavailable_reasons(cooker, pn)
60 if skipreasons:
61 logger.error('\n'.join(skipreasons))
62 else:
63 logger.error("Unable to find any recipe file matching %s" % pn)
64 return recipefile
65
66
67def layer(layerpath):
68 if not os.path.exists(os.path.join(layerpath, 'conf', 'layer.conf')):
69 raise argparse.ArgumentTypeError('{0!r} must be a path to a valid layer'.format(layerpath))
70 return layerpath
71
72
73def newappend(args):
74 import oe.recipeutils
75
76 pn = _provide_to_pn(tinfoil.cooker, args.target)
77 recipe_path = _get_recipe_file(tinfoil.cooker, pn)
78
79 rd = tinfoil.config_data.createCopy()
80 rd.setVar('FILE', recipe_path)
81 append_path, path_ok = oe.recipeutils.get_bbappend_path(rd, args.destlayer, args.wildcard_version)
82 if not append_path:
83 logger.error('Unable to determine layer directory containing %s', recipe_path)
84 return 1
85
86 if not path_ok:
87 logger.warn('Unable to determine correct subdirectory path for bbappend file - check that what %s adds to BBFILES also matches .bbappend files. Using %s for now, but until you fix this the bbappend will not be applied.', os.path.join(destlayerdir, 'conf', 'layer.conf'), os.path.dirname(appendpath))
88
89 layerdirs = [os.path.abspath(layerdir) for layerdir in rd.getVar('BBLAYERS', True).split()]
90 if not os.path.abspath(args.destlayer) in layerdirs:
91 logger.warn('Specified layer is not currently enabled in bblayers.conf, you will need to add it before this bbappend will be active')
92
93 if not os.path.exists(append_path):
94 bb.utils.mkdirhier(os.path.dirname(append_path))
95
96 try:
97 open(append_path, 'a')
98 except (OSError, IOError) as exc:
99 logger.critical(str(exc))
100 return 1
101
102 print(append_path)
103
104
105def register_command(subparsers):
106 parser = subparsers.add_parser('newappend',
107 help='Create a bbappend for the specified target in the specified layer')
108 parser.add_argument('-w', '--wildcard-version', help='Use wildcard to make the bbappend apply to any recipe version', action='store_true')
109 parser.add_argument('destlayer', help='Base directory of the destination layer to write the bbappend to', type=layer)
110 parser.add_argument('target', help='Target recipe/provide to append')
111 parser.set_defaults(func=newappend, parserecipes=True)